如何在 C# 中创建与 BouncyCastle 的 TLS 连接?

TMS*_*ckO 6 c# connection bouncycastle client-certificates tls1.2

我正在尝试使用 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);
Run Code Online (Sandbox Code Playgroud)

下面是 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) { }
}
Run Code Online (Sandbox Code Playgroud)

更新

事实证明,问题是我没有提供带有凭据的签名和哈希算法。添加此解决了问题,我可以连接客户端身份验证。

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;
        }
Run Code Online (Sandbox Code Playgroud)

TMS*_*ckO 0

在问题更新中解决,只需将 SignatureAndHashAlgorithm 添加到我的签名者信用中。