【发布时间】:2021-09-19 20:07:16
【问题描述】:
我正在尝试使用 C# 中的 BouncyCastle 创建具有客户端身份验证的 TLS 连接。但是,我不确定如何正确设置上下文,并且收到异常“TLS 1.2“signatureAndHashAlgorithm”不能为空“”。我的理解是,这来自于 TlsClient 中使用的 DefaultTlsCipherFactory 设置不正确。我是否还需要像拥有其他 Tls 类一样扩展它,还是我还缺少其他东西?
var client = new TcpClient(ip.Address.ToString(), port);
var sr = new SecureRandom();
var protocol = new TlsClientProtocol(client.GetStream(), sr);
var tlsClient = new MyTlsClient(CertChainStructure, PrivateKey);
protocol.Connect(tlsClient);
下面是 MyTlsClient 和 MyTlsAuthentication 类。
class MyTlsClient : DefaultTlsClient
{
private X509CertificateStructure[] CertChain;
private AsymmetricKeyParameter PrivateKey;
public MyTlsClient(X509CertificateStructure[] certChain, AsymmetricKeyParameter privateKey)
{
CertChain = certChain;
PrivateKey = privateKey;
}
public override TlsAuthentication GetAuthentication()
{
return new MyTlsAuthentication(CertChain, PrivateKey, this.mContext);
}
}
class MyTlsAuthentication : TlsAuthentication
{
private Certificate CertChain;
private AsymmetricKeyParameter PrivateKey;
private TlsContext Context;
public MyTlsAuthentication(X509CertificateStructure[] certChain, AsymmetricKeyParameter privateKey, TlsContext context)
{
CertChain = new Certificate(certChain);
Context = context;
PrivateKey = privateKey;
}
public TlsCredentials GetClientCredentials(CertificateRequest certificateRequest)
{
var creds = new DefaultTlsSignerCredentials(Context, CertChain, PrivateKey);
return creds;
}
public void NotifyServerCertificate(Certificate serverCertificate) { }
}
更新
原来问题是我没有提供带有凭据的签名和哈希算法。添加这个解决了这个问题,我可以连接客户端身份验证。
public TlsCredentials GetClientCredentials(CertificateRequest certificateRequest)
{
byte[] certificateTypes = certificateRequest.CertificateTypes;
if (certificateTypes == null || !Arrays.Contains(certificateTypes, ClientCertificateType.rsa_sign))
return null;
SignatureAndHashAlgorithm signatureAndHashAlgorithm = null;
if (certificateRequest.SupportedSignatureAlgorithms != null)
{
foreach (SignatureAndHashAlgorithm alg in certificateRequest.SupportedSignatureAlgorithms)
{
if (alg.Signature == SignatureAlgorithm.rsa)
{
signatureAndHashAlgorithm = alg;
break;
}
}
if (signatureAndHashAlgorithm == null)
return null;
}
var creds = new DefaultTlsSignerCredentials(mContext, CertChain, PrivateKey, signatureAndHashAlgorithm);
return creds;
}
【问题讨论】:
-
我知道这是题外话。但是为什么要使用BC? HttpClient 具有良好的双向 TLS 支持
-
想要在整个握手过程中验证和检查各种事情,即使在连接失败和 BouncyCastle api 的情况下,我似乎可以更轻松地拦截握手的各个部分。
标签: c# connection bouncycastle tls1.2 client-certificates