🔥 告别用户隐私泄露!AWS KMS搞定敏感数据加密(附可直接跑的代码)

4 阅读3分钟

🔥 告别用户隐私泄露!AWS KMS搞定敏感数据加密(附可直接跑的代码)

还在为用户手机号/身份证/银行卡泄露睡不着?

还在愁PCI DSS/网安法合规踩坑?

别再自研加密逻辑、硬编码密钥了!

用AWS KMS做「用户敏感数据读写接口加密」,全程密文不落地,合规+安全双拿捏👇

✨ 核心痛点解决

✅ 敏感字段(身份证/银行卡)传输/存储全程密文,抓包也解不开

✅ 密钥托管在AWS HSM,不用自己管密钥生命周期

✅ 符合GDPR/PCI DSS,审计日志可追溯

✅ 代码直接复用,5分钟集成到Java接口

🚀 具体落地方案(3步走)

步骤1:引入依赖(Maven)

<!-- AWS KMS核心依赖 -->
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>kms</artifactId>
    <version>2.25.0</version>
</dependency>
<!-- AWS SDK核心 -->
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>aws-sdk-java</artifactId>
    <version>2.25.0</version>
</dependency>

步骤2:核心工具类(信封加密/解密)

import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.awssdk.services.kms.model.*;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

// 可直接复制运行!替换你的CMK ARN即可
public class KmsSensitiveDataUtil {
    // 替换成你的KMS主密钥ARN(AWS控制台可查)
    private static final String CMK_ID = "arn:aws:kms:us-east-1:123456789012:key/xxxx-xxxx-xxxx";
    private static final KmsClient KMS_CLIENT = KmsClient.create();

    // 加密敏感数据(接口入参用)
    public static EncryptResult encrypt(String plaintextData) throws Exception {
        // 1. 调用KMS生成数据密钥(明文+密文)
        GenerateDataKeyRequest keyRequest = GenerateDataKeyRequest.builder()
                .keyId(CMK_ID)
                .keySpec(DataKeySpec.AES_256)
                .build();
        GenerateDataKeyResponse keyResponse = KMS_CLIENT.generateDataKey(keyRequest);

        // 2. 明文密钥本地加密数据(用完即销毁,不落地)
        byte[] plainKey = keyResponse.plaintext().asByteArray();
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(plainKey, "AES"));
        byte[] encryptedData = cipher.doFinal(plaintextData.getBytes(StandardCharsets.UTF_8));

        // 3. 返回密文数据+密文密钥(接口传输/存储用)
        return new EncryptResult(
                Base64.getEncoder().encodeToString(encryptedData),
                Base64.getEncoder().encodeToString(keyResponse.ciphertextBlob().asByteArray())
        );
    }

    // 解密敏感数据(接口出参用)
    public static String decrypt(String cipherData, String cipherKey) throws Exception {
        // 1. KMS解密密文密钥
        DecryptRequest decryptRequest = DecryptRequest.builder()
                .ciphertextBlob(Base64.getDecoder().decode(cipherKey))
                .build();
        byte[] plainKey = KMS_CLIENT.decrypt(decryptRequest).plaintext().asByteArray();

        // 2. 本地解密数据
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(plainKey, "AES"));
        byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(cipherData));
        return new String(decryptedData, StandardCharsets.UTF_8);
    }

    // 封装加密结果(接口传输用)
    public static class EncryptResult {
        private String cipherData; // 密文数据
        private String cipherKey;  // 密文密钥
        // 构造器+getter(自行补充)
        public EncryptResult(String cipherData, String cipherKey) {
            this.cipherData = cipherData;
            this.cipherKey = cipherKey;
        }
        public String getCipherData() { return cipherData; }
        public String getCipherKey() { return cipherKey; }
    }
}

步骤3:接口集成(SpringBoot示例)

import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;

@RestController
@RequestMapping("/user")
public class UserSensitiveDataController {

    // 加密存储用户身份证(接口入参密文)
    @PostMapping("/save/idcard")
    public ResponseEntity<Void> saveIdCard(@RequestParam String userId,
                                           @RequestBody KmsSensitiveDataUtil.EncryptResult encryptResult) {
        // 直接存储密文,不落地明文!
        userService.saveIdCard(userId, encryptResult.getCipherData(), encryptResult.getCipherKey());
        return ResponseEntity.ok().build();
    }

    // 解密查询用户身份证(接口出参密文,前端解密)
    @GetMapping("/get/idcard")
    public ResponseEntity<KmsSensitiveDataUtil.EncryptResult> getIdCard(@RequestParam String userId) {
        // 从数据库读取密文数据+密文密钥
        IdCardEntity entity = userService.getIdCard(userId);
        return ResponseEntity.ok(new KmsSensitiveDataUtil.EncryptResult(
                entity.getCipherData(), entity.getCipherKey()
        ));
    }
}

🎯 落地小贴士

  1. 生产环境别硬编码AWS凭证!用EC2/EKS IAM角色
  2. 按业务拆分CMK(比如“用户数据CMK”“支付数据CMK”)
  3. 开启CMK自动轮换(AWS默认每年换,合规要求高可手动换)
  4. 接口加HTTPS,双重保障传输安全

💡 收藏=避坑,转发=救同事!

关注我,下期讲「资金接口KMS签名防篡改」,彻底搞定高风险接口安全!

#AWS #数据安全 #隐私保护 #Java开发 #合规 #KMS #加密