如何使用Google Cloud KMS实现受Adobe信任的PDF认证签名
基于Google Cloud KMS HSM的PDF签名(Java 8)实现指南
前置要求
- 启用Google Cloud KMS API,创建HSM保护的非对称签名密钥:密钥用途选
ASYMMETRIC_SIGN,算法选PDF签名常用的RSA_SIGN_PKCS1_2048_SHA256/RSA_SIGN_PKCS1_4096_SHA256,保护级别必须选HSM,满足Adobe对HSM存储的合规要求 - 申请符合Adobe AATL(Adobe Approved Trust List)要求的数字证书,证书公钥对应KMS创建密钥的公钥即可,申请时向CA提供KMS生成的公钥,私钥全程不会离开KMS HSM硬件
- Java 8项目引入对应版本的Google Cloud KMS SDK和PDF签名工具依赖,推荐用Apache PDFBox处理PDF签名逻辑
核心实现步骤
1. 依赖配置
在项目pom.xml中引入适配Java 8的依赖版本:
<!-- Google Cloud KMS SDK --> <dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-kms</artifactId> <version>1.67.0</version> <!-- 兼容Java 8的稳定版本 --> </dependency> <!-- PDFBox 用于PDF结构处理和签名域嵌入 --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.32</version> <!-- 兼容Java 8的稳定版本 --> </dependency>
2. KMS签名服务封装
替代原有从YML读取本地私钥签名的逻辑,所有签名操作直接调用KMS接口完成:
import com.google.cloud.kms.v1.AsymmetricSignRequest; import com.google.cloud.kms.v1.CryptoKeyVersionName; import com.google.cloud.kms.v1.KeyManagementServiceClient; import com.google.protobuf.ByteString; import java.security.MessageDigest; public class KmsPdfSignService { // 替换为自身KMS密钥的完整路径 private static final String KMS_KEY_RESOURCE_PATH = "projects/你的项目ID/locations/密钥所属区域/keyRings/密钥环名称/cryptoKeys/密钥名称/cryptoKeyVersions/密钥版本号"; // 传入PDF待签名内容的摘要,返回KMS生成的签名值 public byte[] getKmsSignature(byte[] pdfDigest) throws Exception { try (KeyManagementServiceClient kmsClient = KeyManagementServiceClient.create()) { CryptoKeyVersionName keyVersion = CryptoKeyVersionName.parse(KMS_KEY_RESOURCE_PATH); AsymmetricSignRequest signRequest = AsymmetricSignRequest.newBuilder() .setName(keyVersion.toString()) .setDigest(com.google.cloud.kms.v1.Digest.newBuilder() .setSha256(ByteString.copyFrom(pdfDigest)) .build()) .build(); return kmsClient.asymmetricSign(signRequest).getSignature().toByteArray(); } } // 生成PDF内容的SHA256摘要,适配KMS签名输入要求 public byte[] calcPdfSha256Digest(byte[] pdfToSignContent) throws Exception { MessageDigest digest = MessageDigest.getInstance("SHA-256"); return digest.digest(pdfToSignContent); } }
3. 原有存储逻辑替换
- 直接删除YML文件中存储的私钥信息,私钥全程不导出、不落地到本地
- 公钥证书可存储在本地配置或者Google Cloud Storage中,签名时读取证书嵌入PDF的签名域即可
Adobe信任配置说明
- 申请证书的CA必须在Adobe AATL列表范围内,证书颁发后会自动被Adobe Acrobat/Reader信任,无需终端用户手动安装根证书
- 提交CA审核时可直接提供Google KMS公开的FIPS 140-2 Level 3认证文件,满足CA对HSM存储的合规审核要求
注意事项
- 运行Java服务的Google Cloud服务账号需要被授予
roles/cloudkms.cryptoKeySigner角色,否则会出现签名权限不足报错 - KMS密钥的部署区域尽量选择和业务服务同区域,降低签名请求的网络延迟
- 代码中使用的签名算法必须和KMS密钥创建时选择的算法保持一致,否则会出现签名校验失败问题
内容的提问来源于stack exchange,提问作者Antonio De Michele
相关产品推荐
相关产品推荐

