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; } }