Este conteúdo foi traduzido por máquina para sua conveniência e a Huawei Cloud não pode garantir que o conteúdo foi traduzido com precisão. Para exibir o conteúdo original, use o link no canto superior direito para mudar para a página em inglês.
Central de ajuda/ Data Encryption Workshop/ Perguntas frequentes/ Perguntas frequentes/ Relacionado ao KMS/ Como usar uma chave assimétrica para verificar o resultado da assinatura de um par de chaves públicas?
Atualizado em 2024-09-14 GMT+08:00

Como usar uma chave assimétrica para verificar o resultado da assinatura de um par de chaves públicas?

Em cenários em que os pares de chaves públicas e privadas são usados, a chave privada é usada para assinatura e a chave pública é usada para verificação de assinatura. A chave pública pode ser distribuída para o sujeito do serviço que precisa usar a chave pública. O sujeito do serviço verifica a assinatura dos dados de chave. O KMS fornece a API get-publickey para obter chaves públicas.

A CMK RSA_3072 neste caso é usada para verificar assinaturas. Você pode usar o KMS para assinar APIs. O corpo da solicitação é o seguinte:

{
 "key_id": "key_id_value",
 "message": "MTIzNA==",
 "signing_algorithm": "RSASSA_PSS_SHA_256",
 "message_type": "RAW"
}

O resultado é o seguinte:

{
 "key_id": "key_id_value",
 "signature": "xxx"
}

Depois que a chave pública for obtida, certifique-se de que a assinatura seja verificada.

public class RawDataVerifyExample {

    /**
     * Basic authentication information:
     * - ACCESS_KEY: access key of the Huawei Cloud account
     * - SECRET_ACCESS_KEY: Huawei Cloud account secret access key, which is sensitive information. Store this in ciphertext.
     * - IAM_ENDPOINT: endpoint for accessing IAM. For details, see https://developer.huaweicloud.com/intl/en-us/endpoint?IAM.
     * - KMS_REGION_ID: regions supported by KMS. For details, see https://developer.huaweicloud.com/intl/en-us/endpoint?DEW.
     * - KMS_ENDPOINT: endpoint for accessing KMS. For details, see https://developer.huaweicloud.com/intl/en-us/endpoint?DEW.
     */
    private static final String ACCESS_KEY = System.getenv("HUAWEICLOUD_SDK_AK");
    private static final String SECRET_ACCESS_KEY = System.getenv("HUAWEICLOUD_SDK_SK");
    private static final String IAM_ENDPOINT = "https://<IamEndpoint>";
    private static final String KMS_REGION_ID = "<RegionId>";
    private static final String KMS_ENDPOINT = "https://<KmsEndpoint>";

    private static final int SALT_LENGTH = 32;
    private static final int TRAILER_FIELD = 1;
    public static final String RSA_PUBLIC_KEY_BEGIN = "-----BEGIN PUBLIC KEY-----\n";
    public static final String RSA_PUBLIC_KEY_END = "-----END PUBLIC KEY-----";

    // Sample signature data in Base64 encoding format. The original text is 1234.
    private static final String RWA_DATA = "MTIzNA==";

    // Signature value obtained through the sign API of KMS
    private static final String SIGN = "xxx";
    public static void main(String[] args) throws Exception {

        final String keyId = args[0];

        publicKeyVerify(keyId);
    }
   public static void publicKeyVerify(String keyId) throws Exception {

        // 1. Prepare the authentication information for accessing HUAWEI CLOUD.
        final BasicCredentials auth = new BasicCredentials()
                .withIamEndpoint(IAM_ENDPOINT).withAk(ACCESS_KEY).withSk(SECRET_ACCESS_KEY);

        // 2. Initialize the SDK and transfer the authentication information and the address for the KMS to access the client.
        final KmsClient kmsClient = KmsClient.newBuilder()
                .withRegion(new Region(KMS_REGION_ID, KMS_ENDPOINT)).withCredential(auth).build();

        // 3. Obtain the public key information. The returned information is in PKCS8 format.
        final ShowPublicKeyRequest showPublicKeyRequest = new ShowPublicKeyRequest()
                .withBody(new OperateKeyRequestBody().withKeyId(keyId));
        final ShowPublicKeyResponse showPublicKeyResponse = kmsClient.showPublicKey(showPublicKeyRequest);

        // 4. Obtain the public key string.
        final String publicKeyStr = showPublicKeyResponse.getPublicKey().replace(RSA_PUBLIC_KEY_BEGIN, "")
                .replaceAll("\n", "").replace(RSA_PUBLIC_KEY_END, "");

        // 5. Parse the public key.
        final X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyStr));
        final KeyFactory keyFactory = KeyFactory.getInstance("RSA", new BouncyCastleProvider());
        final PublicKey publicKey = keyFactory.generatePublic(keySpec);

        // 6. Verify the signature.
        final Signature signature = getSignature();
        signature.initVerify(publicKey);
        signature.update(commonHash(Base64.getDecoder().decode(RWA_DATA)));

        // 7. Obtain the verification result.
        assert signature.verify(Base64.getDecoder().decode(SIGN));

    }
    private static Signature getSignature() throws Exception {
        Signature signature= Signature.getInstance("NONEwithRSASSA-PSS", new BouncyCastleProvider());
        MGF1ParameterSpec mgfParam = new MGF1ParameterSpec("SHA256");
        PSSParameterSpec pssParam = new PSSParameterSpec("SHA256", "MGF1", mgfParam, SALT_LENGTH, TRAILER_FIELD);
        signature.setParameter(pssParam);
        return signature;
    }
    private static byte[] commonHash(byte[] data) {
        byte[] digest;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA256", BouncyCastleProvider.PROVIDER_NAME);
            md.update(data);
            digest = md.digest();
        } catch (Exception e) {
            throw new RuntimeException("Digest failed.");
        }
        return digest;
    }
}