4

我的 .Net 核心应用程序使用 HttpClient 向外部 Web 服务发出 post 请求。外部 Web 服务需要一个证书来进行验证。

证书安装在 AWS 中,我有一个指向证书的 ARN。

是否可以从 AWS Certificate Manager 以编程方式获取证书并在我的 HtppClient 中使用它,例如这是我通常用来添加证书的代码,但我需要从 AWS 获取它。

   private HttpClientHandler HttpClientHandler()
   {
        var handler = new HttpClientHandler
        {
            ClientCertificateOptions = ClientCertificateOption.Manual,
            SslProtocols = SslProtocols.Tls12
        };
        handler.ClientCertificates.Add(new X509Certificate2("cert.crt")); //TODO: fetch from AWS.
        return handler;
    }
4

3 回答 3

7

所以,这是可能的。

我从 NuGet 安装了 AWSSDK.Core 和 AWSSDK.CertificateManager。

然后,我为 AWS 创建了一个凭证文件,请参阅 Amazon https://docs.aws.amazon.com/cli/latest/userguide/cli-config-files.html的说明

接下来,我使用 AmazonCertificateManagerClient 获取证书。

AmazonCertificateManagerClient client = new AmazonCertificateManagerClient();
var certificates = client.GetCertificateAsync(arn).Result;

然后我将证书从字符串转换为字节,然后添加到处理程序中。

var handler = new HttpClientHandler{
  ClientCertificateOptions = ClientCertificateOption.Manual,
  SslProtocols = SslProtocols.Tls12
};

byte[] toBytes = Encoding.ASCII.GetBytes(certificates.Certificate);
var cert = new X509Certificate2(toBytes);

handler.ClientCertificates.Add(cert); 
var httpClient = new HttpClient(handler);

显然,不是值得生产的代码,希望它有所帮助。

于 2018-09-10T13:36:14.723 回答
2

如果您使用 AWS 开发工具包,您可以使用AmazonCertificateManagerClient. 有关详细信息,请参阅AWS 开发工具包文档。(选择Amazon.CertificateManager> AmazonCertificateManagerClient

于 2018-09-10T12:27:30.020 回答
2

正如扎克所说,接受的答案不起作用。它确实从 ACM 中检索证书,但它不能用作 HttpClient 的客户端证书,因为它没有私钥。

据我所知,没有办法从 ACM 中获取私钥,所以我最终将它放在 SecretsManager 中并执行以下操作:

var certManagerClient = new AmazonCertificateManagerClient();
var awsCert = certManagerClient.GetCertificateAsync(arn).Result;
byte[] awsBytes = Encoding.ASCII.GetBytes(awsCert.Certificate);
var cert = new X509Certificate2(awsBytes);

var secretsManagerClient = new AmazonSecretsManagerClient();
var privateKey = secretsManagerClient.GetSecretValueAsync(new GetSecretValueRequest { SecretId = secretId }).Result.SecretString;
byte[] privateKeyBytes = Convert.FromBase64String(privateKey);
var privateKey = RSA.Create();
privateKey.ImportRSAPrivateKey(new ReadOnlySpan<byte>(privateKeyBytes), out _);
var certWithPrivateKey = cert.CopyWithPrivateKey(privateKey);

然后在我的 HttpClientHandler 中使用 certWithPrivateKey:

var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Manual };
handler.ClientCertificates.Add(certWithPrivateKey);
于 2021-04-08T05:31:40.223 回答