簡體   English   中英

無法在客戶端新X509Certificate2()解碼證書

[英]Unable to decode certificate at client new X509Certificate2()

我正在使用這個小類 ,它返回一個字節數組中的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

在Mono.Security.X509.X509Certificate.PEM(System.String類型,System.Byte []數據)[0x00000] in:0

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

使用X509Certificate2構造函數加載帶有空密碼的PKCS#12時,Mono中存在一個錯誤。 已提交修補程序以解決此問題,但它(可能)未在您的mono版本中發布。

嘗試將字節保存到文件,然后使用new X509Certificate2(filepath, String.Empty)new X509Certificate2(filepath, null)或使用一些默認的非空密碼創建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文檔頁面上提供的其他示例不同,此解決方案似乎運行良好。 我希望這也能幫助別人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM