无法在客户端新X509Certificate2()

时间:2015-12-29 01:08:43

标签: c# ssl x509certificate2

我正在使用这个little class,它在字节数组中返回一个pfx文件。

服务器端:

byte[] serverCertificatebyte;
var date = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day);
serverCertificatebyte = Certificate.CreateSelfSignCertificatePfx("CN=RustBuster" + RandomString(5),
    date,
    date.AddDays(7));

然后我发送给客户(长度:1654):

tcpClient.GetStream().Write(serverCertificatebyte , 0, serverCertificatebyte .Length);

一旦客户端读取它,我想将其转换为证书类: (这里长度也是1654)

我尝试做一个新的X509Certificate2(数据);我在下面得到错误。这适用于服务器端。怎么了?

我也尝试了新的X509Certificate2(data,string.Empty);并得到了同样的错误

  

错误System.Security.Cryptography.CryptographicException:无法解码证书。 ---> System.Security.Cryptography.CryptographicException:输入数据无法编码为有效证书。 ---> System.ArgumentOutOfRangeException:不能为负。

参数名称:长度

在System.String.Substring(Int32 startIndex,Int32 length)[0x00000] in:0

at Mono.Security.X509.X509Certificate.PEM(System.String type,System.Byte [] data)[0x00000] in:0

at Mono.Security.X509.X509Certificate..ctor(System.Byte [] data)[0x00000] in:0

2 个答案:

答案 0 :(得分:3)

使用X509Certificate2构造函数加载带有空密码的PKCS#12时,Mono中存在一个错误。已提交patch来解决此问题,但它(可能)未在您的单声道版本中发布。

尝试将字节保存到文件中,然后使用new X509Certificate2(filepath, String.Empty)new X509Certificate2(filepath, null)或使用默认的非空密码创建pfx。

答案 1 :(得分:1)

长期的想法和帮助请求最终引导我找到解决方案。

以下方式或示例到我一直没有工作的持久连接。

在服务器端,首先必须获取要发送的字节的长度,然后将其写入流。这很可能是一个长度为4的字节。

byte[] intBytes = BitConverter.GetBytes(serverCertificatebyte.Length);
Array.Reverse(intBytes);

在客户端,读取该字节,并将其转换为int:

byte[] length = new byte[4];
int red = 0;
while (true)
{
    red = stream.Read(length, 0, length.Length);
    if (red != 0)
    {
        break;
    }
}
if (BitConverter.IsLittleEndian)
{
    Array.Reverse(length);
}
int i = (BitConverter.ToInt32(length, 0)); // The length of the byte that the server sent
// By this time your server already sent the byte (Right after you sent the length) tcpClient.GetStream().Write(byte, 0, byte.Length);
byte[] data = ByteReader(i);

此方法将读取您从服务器发送的字节,直到可能

internal byte[] ByteReader(int length)
{
    using (NetworkStream stream = client.GetStream())
    {
        byte[] data = new byte[length];
        using (MemoryStream ms = new MemoryStream())
        {
            int numBytesRead;
            int numBytesReadsofar = 0;
            while (true)
            {
                numBytesRead = stream.Read(data, 0, data.Length);
                numBytesReadsofar += numBytesRead;
                ms.Write(data, 0, numBytesRead);
                if (numBytesReadsofar == length)
                {
                    break;
                }
            }
            return ms.ToArray();
        }
    }
}

与microsoft文档页面上提供的其他示例不同,此解决方案似乎运行良好。我希望这也能帮助别人。