2016-08-01 68 views
0

我需要知道什麼編碼C#ECDsaCng.SignData在OpenSSL中使用簽名?

https://msdn.microsoft.com/en-us/library/bb347054(v=vs.110).aspx

ECDsaCng.SignData方法(Byte [])

使用的默認情況下它的字節數組,以及如何將它轉換成由

接受了DER格式

https://www.openssl.org/docs/manmaster/crypto/i2d_ECDSA_SIG.html

,這樣我可以驗證我的C#中使用的方法ECDSA_do_verify產生ECSDA簽名的OpenSSL。

我知道它的SHA1,我知道如何加載該摘要,我只是不知道ECDsaCng.SignData方法的字節編碼是什麼,也不知道如何將它轉換爲DER格式,如果我甚至需要這樣做。

+0

你已經提到了C#中的DSA和OpenSSL中的ECDSA;哪種算法是你實際嘗試使用的?他們是不一樣的... – bartonjs

+0

對不起,ECDsaCng.SignData方法(字節[])是什麼意思.. – Akumaburn

+0

也請注意,任何人讀這個正確的函數是SignHash,因爲ECDSA_do_verify需要一個已知的摘要,SignData將重新哈希與.NET默認的任何東西,這是什麼導致我很麻煩。有一個使用C#鍵進行OpenSSL驗證的實現,我在我的個人檔案中的其中一個問題中已經提出了您可能想要查看的問題。這也許是有幫助的:http://stackoverflow.com/questions/24251336/import-a-public-key-from-somewhere-else-to-cngkey – Akumaburn

回答

1

ECDSA簽名是價值對(r, s)

Windows CNG將此作爲這兩個值的串聯發出,並且由於.NET不重新解釋數據,因此這是事實上的.NET格式。 (r是陣列的前半部分,s是下半部分)

OpenSSL需要SEQUENCE(INTEGER(r),INTEGER(s))的DER編碼結構。這鬆散地意味着{ 0x30, payload_length, 0x02, r_length, r_bytes[0]...r_bytes[r_length-1], 0x02, s_length, s_bytes[0]...s_bytes[s_length-1] };雖然它比這個稍微複雜一點,因爲當r_bytes [0]或s_bytes [0]> = 0x80(因爲這會使其顯示爲負數)時需要填充字節。

不幸的是,默認情況下,框架中沒有通用的DER編碼器。

如果您嘗試在Linux上運行,那麼可以通過使用.NET Core更好地服務,因爲ECDSA實現了Linux already does這一數據轉換。

+0

它恰好是數組的一半嗎?那麼r和s的大小是否相等?如果不是,我如何確定它(r或s)何時開始和結束? – Akumaburn

+0

那麼,.NET Core肯定會將其解釋爲始終大小相等(因此blob應該始終具有均勻的長度)。由於Windows還沒有足夠的信息來知道額外(或不足)的字節是來自r還是s,因此他們使用剛性輸出似乎很合理。 – bartonjs