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.
Atualizado em 2024-09-14 GMT+08:00

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.

Figura 1 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.

Figura 2 Processo de verificação de assinatura.

Procedimento

  1. 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.

  2. Obtenha informações da região.

  3. 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());
            }
        }
     
    }