Saya menghadapi masalah yang sama ketika bekerja dengan sertifikat yang ditandatangani sendiri dan autentikasi sertifikat klien pada wadah .NET Core 2.2 dan Docker Linux. Semuanya bekerja dengan baik di mesin Windows dev saya, tetapi di Docker saya mendapat kesalahan seperti itu:
System.Security.Authentication.AuthenticationException: Sertifikat jarak jauh tidak valid sesuai dengan prosedur validasi
Untungnya, sertifikat dibuat menggunakan rantai. Tentu saja, Anda selalu dapat mengabaikan solusi ini dan menggunakan solusi di atas.
Jadi inilah solusi saya:
Saya menyimpan sertifikat menggunakan Chrome di komputer saya dalam format P7B .
Ubah sertifikat ke format PEM menggunakan perintah ini:
openssl pkcs7 -inform DER -outform PEM -in <cert>.p7b -print_certs > ca_bundle.crt
Buka file ca_bundle.crt dan hapus semua rekaman Subjek, biarkan file bersih. Contoh di bawah ini:
-----BEGIN CERTIFICATE-----
_BASE64 DATA_
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
_BASE64 DATA_
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
_BASE64 DATA_
-----END CERTIFICATE-----
- Letakkan baris ini ke Dockerfile (di langkah terakhir):
# Update system and install curl and ca-certificates
RUN apt-get update && apt-get install -y curl && apt-get install -y ca-certificates
# Copy your bundle file to the system trusted storage
COPY ./ca_bundle.crt /usr/local/share/ca-certificates/ca_bundle.crt
# During docker build, after this line you will get such output: 1 added, 0 removed; done.
RUN update-ca-certificates
- Di aplikasi:
var address = new EndpointAddress("https://serviceUrl");
var binding = new BasicHttpsBinding
{
CloseTimeout = new TimeSpan(0, 1, 0),
OpenTimeout = new TimeSpan(0, 1, 0),
ReceiveTimeout = new TimeSpan(0, 1, 0),
SendTimeout = new TimeSpan(0, 1, 0),
MaxBufferPoolSize = 524288,
MaxBufferSize = 65536,
MaxReceivedMessageSize = 65536,
TextEncoding = Encoding.UTF8,
TransferMode = TransferMode.Buffered,
UseDefaultWebProxy = true,
AllowCookies = false,
BypassProxyOnLocal = false,
ReaderQuotas = XmlDictionaryReaderQuotas.Max,
Security =
{
Mode = BasicHttpsSecurityMode.Transport,
Transport = new HttpTransportSecurity
{
ClientCredentialType = HttpClientCredentialType.Certificate,
ProxyCredentialType = HttpProxyCredentialType.None
}
}
};
var client = new MyWSClient(binding, address);
client.ClientCredentials.ClientCertificate.Certificate = GetClientCertificate("clientCert.pfx", "passwordForClientCert");
client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
{
CertificateValidationMode = X509CertificateValidationMode.ChainTrust,
TrustedStoreLocation = StoreLocation.LocalMachine,
RevocationMode = X509RevocationMode.NoCheck
};
Metode GetClientCertificate:
private static X509Certificate2 GetClientCertificate(string clientCertName, string password)
{
byte[] rawData = null;
using (var f = new FileStream(Path.Combine(AppContext.BaseDirectory, clientCertName), FileMode.Open, FileAccess.Read))
{
var size = (int)f.Length;
var rawData = new byte[size];
f.Read(rawData, 0, size);
f.Close();
}
return new X509Certificate2(rawData, password);
}