Можно ли в приложении.NET Core получить сертификат из AWS Certificate Manager и использовать его в сообщении HttpClient?

Моё основное приложение.Net отправляет запрос во внешний веб-сервис, используя HttpClient. Внешний веб-сервис требует сертификат для проверки.

Сертификаты установлены в 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;
    }

3 ответа

Так что это возможно.

Я установил AWSSDK.Core и AWSSDK.CertificateManager от NuGet.

Затем я создал файл учетных данных для 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);

Очевидно, что не код, достойный производства, надеюсь, это поможет.

Как упоминал Зак, принятый ответ не работает. Он действительно извлекает сертификат из 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);

А затем с помощью certWithPrivateKey в моем HttpClientHandler:

      var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Manual };
handler.ClientCertificates.Add(certWithPrivateKey);

Если вы используете AWS SDK, вы можете получить сертификаты, используя AmazonCertificateManagerClient, Для получения дополнительной информации см. Документацию AWS SDK. (Выбрать Amazon.CertificateManager > AmazonCertificateManagerClient)

Другие вопросы по тегам