我有一个可行的实现,但想确保它是安全的。目标是使用 SSLStream 并且只接受来自服务器的由特定 RSA 密钥签名的 SSL 证书。
这是我的连接代码:
var client = new TcpClient("server_address", port_number);
var sslStream = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
sslStream.AuthenticateAsClient("SpeechGrid");
这是我对 ValidateServerCertificate 的实现:
private static bool ValidateServerCertificate(object sender, X509Certificate certificate,
X509Chain chain, SslPolicyErrors sslPolicyErrors) {
// Only accept our specific key pair
foreach (var cert in chain.ChainElements) {
if (cert.Certificate.GetPublicKeyString() == k_prodPublicKey) {
return true;
}
}
return false;
}
由于 X509Chain 对象的丰富性,我想确保不需要检查 X509ChainStatusFlags.NotSignatureValid 等内容。
例如,攻击者是否有可能“声称”由我的公钥签名,发送无效签名,并且这种攻击会起作用,因为 .NET 假设我正在检查所有这些标志?
谢谢!!
更新:好的,到目前为止,我决定将以下检查放在原始 foreach 之上。请注意,这在某种程度上是特定于应用程序的;例如,如果我希望证书过期,我会检查 NotTimeValid 等。
foreach (var status in chain.ChainStatus) {
switch (status.Status) {
case X509ChainStatusFlags.Cyclic:
case X509ChainStatusFlags.NotSignatureValid:
case X509ChainStatusFlags.PartialChain:
return false;
}
}