Я хочу реализовать закрепление сертификата / открытого ключа в моем приложении C #.Я уже видел много решений, которые прикрепляют сертификат сервера напрямую, например, в этот вопрос .Однако для большей гибкости я хочу прикрепить только корневой сертификат.Сертификат, который сервер получает при настройке, подписан промежуточным центром сертификации, который сам подписан корнем.
До сих пор я реализовал сервер, который загружает свой собственный сертификат, закрытый ключ, промежуточный сертификат икорневой сертификат из файла PKCS # 12 (.pfx).Я создал файл с помощью следующей команды:
openssl pkcs12 -export -inkey privkey.pem -in server_cert.pem -certfile chain.pem -out outfile.pfx
Файл chain.pem содержит корневой и промежуточный сертификат.
Сервер загружает этот сертификат и хочетаутентифицируйте себя на клиенте:
// certPath is the path to the .pfx file created before
var cert = new X509Certificate2(certPath, certPass)
var clientSocket = Socket.Accept();
var sslStream = new SslStream(
new NetworkStream(clientSocket),
false
);
try {
sslStream.AuthenticateAsServer(cert, false, SslProtocols.Tls12, false);
} catch(Exception) {
// Error during authentication
}
Теперь клиент хочет аутентифицировать сервер:
public void Connect() {
var con = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
con.Connect(new IPEndPoint(this.address, this.port));
var sslStream = new SslStream(
new NetworkStream(con),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
);
sslStream.AuthenticateAsClient("serverCN");
}
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors
)
{
// ??
}
Проблема в том, что сервер отправляет клиенту только свой собственный сертификат.Также параметр chain не содержит дополнительной информации.Это как-то правдоподобно, поскольку сертификат X509Certificate2 (в коде сервера) содержит только сертификат сервера и не содержит никакой информации о промежуточном или корневом сертификате.Однако клиент не может проверить всю цепочку, поскольку (по крайней мере) промежуточный сертификат отсутствует.
До сих пор я не нашел возможности заставить .NET отправлять всю цепочку сертификатов, но яне хотите закреплять сертификат сертификата сервера iself или промежуточный, поскольку это нарушает гибкость закрепления корневого сертификата.
Следовательно, кто-нибудь знает возможность заставить SslStream отправлять всю цепочку для аутентификации или реализовывать функциональность с использованиемдругой подход?Или я должен по-разному упаковывать сертификаты?
Спасибо!
Редактировать: Я сделал несколько других тестов, чтобы обнаружить проблему.Как предлагается в комментариях, я создал X509Store
, который содержит все сертификаты.После этого я собрал X509Chain
, используя сертификат моего сервера и хранилище.На самом сервере новая цепочка правильно содержит все сертификаты, но не в функции ValidateServerCertificate
.