You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于AWS ACM PCA与KMS的MTLS认证及签名实现疑问

解决方案:基于AWS KMS实现MTLS认证与数据签名(无导出私钥)

核心思路

既然KMS私钥不可导出,需拆分MTLS认证和数据签名的实现逻辑,利用KMS的密钥操作API直接完成签名,同时通过证书与KMS密钥绑定的方式实现MTLS客户端认证。

方案1:MTLS认证用ACM PCA证书,签名直接调用KMS API

  • MTLS客户端认证部分:

    1. 先在KMS创建非对称密钥对,导出公钥后提交给ACM PCA签发客户端证书,确保证书公钥与KMS密钥公钥完全匹配。
    2. 将ACM PCA颁发的客户端证书单独存储(无需本地保存私钥)。
    3. 自定义TLS密钥管理器,在TLS握手需要私钥签名时(如证书验证阶段),直接调用KMS的Sign API完成签名,替代从本地PKCS#12读取私钥的逻辑。
  • 数据签名部分:
    直接调用KMS的Sign API,传入待签名数据、密钥ID和匹配的签名算法(如SHA256withRSA),全程无需在本地处理私钥。

方案2:ACM PCA与KMS集成托管密钥

  • 配置ACM PCA使用KMS作为密钥存储(需启用两者的集成功能),让证书对应的私钥直接由KMS托管,无需导出。
  • MTLS握手时,TLS层通过集成自动调用KMS完成私钥签名操作,无需额外开发自定义密钥管理器。
  • 数据签名同样复用该KMS密钥,直接调用Sign API即可。

关键代码示例(Java)

自定义TLS密钥管理器对接KMS签名

import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.awssdk.services.kms.model.SignRequest;
import software.amazon.awssdk.services.kms.model.SignResponse;
import javax.net.ssl.X509KeyManager;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.net.Socket;
import java.security.Principal;

public class KmsX509KeyManager implements X509KeyManager {
    private final X509Certificate[] clientCerts;
    private final String kmsKeyId;
    private final KmsClient kmsClient;

    public KmsX509KeyManager(X509Certificate[] clientCerts, String kmsKeyId, KmsClient kmsClient) {
        this.clientCerts = clientCerts;
        this.kmsKeyId = kmsKeyId;
        this.kmsClient = kmsClient;
    }

    @Override
    public String[] getClientAliases(String keyType, Principal[] issuers) {
        return new String[]{"kms-client-key"};
    }

    @Override
    public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
        return "kms-client-key";
    }

    @Override
    public PrivateKey getPrivateKey(String alias) {
        // 返回自定义PrivateKey实现,签名逻辑委托给KMS
        return new PrivateKey() {
            @Override
            public String getAlgorithm() {
                return "RSA";
            }

            @Override
            public String getFormat() {
                return "KMS";
            }

            @Override
            public byte[] getEncoded() {
                throw new UnsupportedOperationException("KMS私钥无法导出");
            }
        };
    }

    @Override
    public X509Certificate[] getCertificateChain(String alias) {
        return clientCerts;
    }

    // 其余未实现方法可按需补充或返回null
}

KMS数据签名调用示例

public byte[] signDataWithKms(String kmsKeyId, byte[] rawData) {
    SignRequest signReq = SignRequest.builder()
            .keyId(kmsKeyId)
            .signingAlgorithm("SHA256_WITH_RSA")
            .message(rawData)
            .messageType("RAW")
            .build();
    SignResponse signResp = kmsClient.sign(signReq);
    return signResp.signature().asByteArray();
}

注意事项

  • 确保IAM角色拥有kms:Sign、acm-pca:GetCertificate等必要API权限。
  • TLS握手使用的签名算法必须与KMS密钥支持的算法匹配(如RSA或EC系列)。
  • 若使用EC密钥,需确认ACM PCA支持对应的椭圆曲线(如secp256r1)。

内容的提问来源于stack exchange,提问作者user3677636

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 23:05:25