Uso do KMS para proteger a integridade dos arquivos
Cenário
Quando uma grande quantidade de arquivos (como imagens, apólices de seguro eletrônicas e arquivos importantes) precisar ser transmitida ou armazenada com segurança, você poderá usar o KMS para assinar o resumo do arquivo. Quando os arquivos são usados novamente, você pode recalcular o resumo para verificação de assinatura. Certifique-se de que os arquivos não sejam adulterados durante a transmissão ou armazenamento.
Solução
Crie uma CMK no KMS.
Calcule o resumo do arquivo e chame a API de assinatura do KMS para assinar o resumo. O resultado da assinatura do resumo é obtido. Transmita ou armazene o resultado da assinatura do resumo, o ID da chave e o arquivo juntos. A figura a seguir mostra o processo de assinatura.
Antes de usar um arquivo, você precisa verificar a integridade do arquivo para garantir que o arquivo não seja adulterado.
Recalcule o resumo do arquivo e chame a API de verificação do KMS com o valor da assinatura para verificar a assinatura do resumo. O resultado da verificação da assinatura é obtido. Se a assinatura for verificada, o arquivo não foi adulterado. A figura a seguir mostra o processo de verificação de assinatura.
Procedimento
- Obtenha o AK e a SK.
- ACCESS_KEY: chave de acesso da conta da Huawei. Para obter detalhes, consulte Como obter uma chave de acesso (AK/SK)?
- SECRET_ACCESS_KEY: chave de acesso de segredo da conta da Huawei. Para obter detalhes, consulte Como obter uma chave de acesso (AK/SK)?
- Haverá riscos de segurança se a AK/SK usada para autenticação for gravada diretamente no código. Criptografe a AK/SK no arquivo de configuração ou nas variáveis de ambiente para armazenamento.
- Neste exemplo, a AK/SK armazenada nas variáveis de ambiente é usada para autenticação de identidade. Configure as variáveis de ambiente HUAWEICLOUD_SDK_AK e HUAWEICLOUD_SDK_SK primeiro no ambiente local.
- Obtenha informações da região.
- Use o KMS para assinar o arquivo e verificar a assinatura.
public class FileStreamSignVerifyExample { /** * Basic authentication information: * - ACCESS_KEY: access key of the Huawei Cloud account * - SECRET_ACCESS_KEY: secret access key of the Huawei Cloud account, which is sensitive information. Store this in ciphertext. * - IAM_ENDPOINT: endpoint for accessing IAM. For details, see Regions and Endpoints. * - KMS_REGION_ID: regions supported by KMS. For details, see Regions and Endpoints. * - KMS_ENDPOINT: endpoint for accessing KMS. For details, see Regions and Endpoints. */ 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>"; public static void main(String[] args) { // CMK ID. Select a key whose usage contains SIGN_VERIFY. final String keyId = args[0]; signAndVerifyFile(keyId); } /** * Use KMS to sign the file and verify the signature. * * @param keyId: CMK ID */ static void signAndVerifyFile(String keyId) { // 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. Prepare the file to be signed. // inFile File to be signed final File inFile = new File("FirstSignFile.iso"); final String fileSha256Sum = getFileSha256Sum(inFile); // 4. Calculate the digest and select a proper signature algorithm based on the key type. final SignRequest signRequest = new SignRequest().withBody( new SignRequestBody().withKeyId(keyId).withSigningAlgorithm(SignRequestBody.SigningAlgorithmEnum.RSASSA_PSS_SHA_256) .withMessageType(SignRequestBody.MessageTypeEnum.DIGEST).withMessage(fileSha256Sum)); final SignResponse signResponse = kmsClient.sign(signRequest); // 5. Verify the digest. final ValidateSignatureRequest validateSignatureRequest = new ValidateSignatureRequest().withBody( new VerifyRequestBody().withKeyId(keyId).withMessage(fileSha256Sum).withSignature(signResponse.getSignature()) .withSigningAlgorithm(VerifyRequestBody.SigningAlgorithmEnum.RSASSA_PSS_SHA_256) .withMessageType(VerifyRequestBody.MessageTypeEnum.DIGEST)); final ValidateSignatureResponse validateSignatureResponse = kmsClient.validateSignature(validateSignatureRequest); // 6. Compare the digest result. assert validateSignatureResponse.getSignatureValid().equalsIgnoreCase("true"); } /** * Calculate the SHA256 digest of the file. * * @param file * @return SHA256 digest in Base64 format */ static String getFileSha256Sum(File file) { int length; MessageDigest sha256; byte[] buffer = new byte[1024]; try { sha256 = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e.getMessage()); } try (FileInputStream inputStream = new FileInputStream(file)) { while ((length = inputStream.read(buffer)) != -1) { sha256.update(buffer, 0, length); } return Base64.getEncoder().encodeToString(sha256.digest()); } catch (IOException e) { throw new RuntimeException(e.getMessage()); } } }