天天看點

C#利用Java的RSA密鑰對,與Java進行通通訊

C#利用Java的RSA密鑰對,與Java進行通通訊

一.RSA算法簡介

關于RSA加密算法可以參考:

http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95

大體是先生成兩個大素數p和q,再生成e,e和(p-1)*(q-1)互素。

取p和q的乘積:n=p*q 為公共模數。

再生成正整數d,滿足d*e-1可以被(p-1)*(q-1)整除。

這樣d就為私鑰,(e,n)為公鑰,形成rsa的公私鑰對。

其中n的二進制位稱為該密鑰長度,密鑰越長越難破解,也就越安全。

二. C#與java互通加解密

2.1不能直接使用的.net封裝的RSA緣由:

預設情況下,.NET生成的RSA密鑰對可以用XML或位元組流來儲存,而JAVA中生成的RSA密鑰對隻能用位元組流來儲存。而它們的位元組流格式不同,就導緻Java中生成的RSA密鑰對不能在.NET中使用,而.NET中生成的密鑰對又不能在Java中使用。(這也是我為什麼要寫這篇博文的緣由)

Java是PKCS #8 編碼(PKCS #8使用 ASN.1 的 DER 編碼規則)。

C#是Base64編碼。

其次,.Net自帶的RSA加密解密類RSACryptoServiceProvider,你在執行個體(new)它時就自帶有相關參數,如一下代碼所示(列印相關參數Modulus,Exponent,D,其中Modulus+Exponent為公鑰,D為私鑰,C#裡是以base64格式儲存的。)

是以若要指定RSACryptoServiceProvider,就要知道Modulus,Exponent,D對應的值,然後為其指派。但是Java也是調用自己類庫,隻提供了密鑰對。

2.2填充算法:

由于密鑰長度有限,一次性加密的資料長度也有限,是以必須對明文進行分塊加密,再合并加密結果。以1024位密鑰為例,n為1024位,即128個位元組,則明文需要分塊成每塊長128個位元組,不足128位的使用特定格式的資料填充。是以分塊的算法稱為填充算法,有不同的标準,如NoPPadding、OAEPPadding、PKCS1Padding等。

三. RSA加密解密位元組長度限制

加密:RSA 1024表示加密後的長度為1024位,即128個位元組,但明文的最大長度不能超過117個位元組( 如果資料長度超過128byte,就會被分割為幾段進行加密,最後把加密結果轉換為16進制字元串,并連接配接起來輸出結果。)

解密:一般情況下,128byte的資料,加密後輸出的hex字元串應該是256byte,是以對應的解密方法為:把加密後的hex字元串按256byte進行拆分,分别解密,最後得到原文。

(轉化為十六進制字元串,便于用于Web傳遞)

注:網絡上有些使用大整數類(BigIneger類)處理資料長度超過以上值的問題,本人試過,雖然能解密出來,但是解密出來的明文中還是有亂碼。

當然,說了這麼多,不如上一個Demo來的簡單,附件便是C#寫的RSA加密解密。

簡單流程圖如下:

C#利用Java的RSA密鑰對,與Java進行通通訊