无法在客户端解码证书 new X509Certificate2()
Unable to decode certificate at client new X509Certificate2()
我正在使用这个 little class,它 returns 我是字节数组中的 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);
客户端阅读后,我想将其转换为证书class:
(这里长度也是1654)
我尝试做一个新的 X509Certificate2(data);我在下面得到了错误。这适用于服务器端。怎么了?
我也用 new X509Certificate2(data, string.Empty) 试过了;得到了同样的错误
Error System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Cannot be negative.
参数名称:长度
at System.String.Substring (Int32 startIndex, Int32 length) [0x00000] in :0
at Mono.Security.X509.X509Certificate.PEM(System.String 类型,System.Byte[] 数据)[0x00000] in :0
at Mono.Security.X509.X509Certificate..ctor(System.Byte[] 数据)[0x00000] in :0
当使用 X509Certificate2 构造函数加载密码为空的 PKCS#12 时,Mono 中存在错误。已提交 patch 来修复此问题,但它(可能)未在您的 mono 版本中发布。
尝试将字节保存到文件中,然后使用 new X509Certificate2(filepath, String.Empty)
或 new X509Certificate2(filepath, null)
或使用一些默认 non-empty 密码创建 pfx。
漫长的思考和帮助请求终于让我找到了解决方案。
以下持久连接的方法或示例根本不起作用。
在服务器端,您首先必须获取要发送的字节的长度,并将其写入流。这很可能是一个长度为 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 文档页面上提供的其他示例不同,此解决方案似乎运行良好。我希望这也会对其他人有所帮助。
我正在使用这个 little class,它 returns 我是字节数组中的 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);
客户端阅读后,我想将其转换为证书class: (这里长度也是1654)
我尝试做一个新的 X509Certificate2(data);我在下面得到了错误。这适用于服务器端。怎么了?
我也用 new X509Certificate2(data, string.Empty) 试过了;得到了同样的错误
Error System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Cannot be negative.
参数名称:长度
at System.String.Substring (Int32 startIndex, Int32 length) [0x00000] in :0
at Mono.Security.X509.X509Certificate.PEM(System.String 类型,System.Byte[] 数据)[0x00000] in :0
at Mono.Security.X509.X509Certificate..ctor(System.Byte[] 数据)[0x00000] in :0
当使用 X509Certificate2 构造函数加载密码为空的 PKCS#12 时,Mono 中存在错误。已提交 patch 来修复此问题,但它(可能)未在您的 mono 版本中发布。
尝试将字节保存到文件中,然后使用 new X509Certificate2(filepath, String.Empty)
或 new X509Certificate2(filepath, null)
或使用一些默认 non-empty 密码创建 pfx。
漫长的思考和帮助请求终于让我找到了解决方案。
以下持久连接的方法或示例根本不起作用。
在服务器端,您首先必须获取要发送的字节的长度,并将其写入流。这很可能是一个长度为 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 文档页面上提供的其他示例不同,此解决方案似乎运行良好。我希望这也会对其他人有所帮助。