如何在 C# 中使用 BouncyCastle 创建 TLS 连接?

How to create a TLS connection with BouncyCastle in C#?

我正在尝试使用 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;
        }

已在 UPDATE 中解决问题,只需将 SignatureAndHashAlgorithm 添加到我的签名者凭据中即可。