Можно ли в приложении.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
)