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加密解密。
簡單流程圖如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnaukzNycDNxQTNx8CXwEzMxAjMvwFduVWboNWY0RXYvwVbvNmLvR3YxUjL3M3Lc9CX6MHc0RHaiojIsJye.jpg)