C#與Java的RSA(3)
原創文章,轉載請註明出處 http://boytnt.blog.51cto.com/966121/1351207。
在上一篇文章裡,我們已經成功的解析出了公鑰加密至關重要的modulus和publicExponent,勝利在望,心急的同學肯定要開始這麼寫了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/*********** C#程式碼 ***********/ //設定RSA引數,用於指定modulus和exponent var parameter = new RSAParameters();
parameter.Modulus = modulusBytes; //modulusBytes是轉化後的byte[]
parameter.Exponent = exponentBytes; //加密 var rsa = RSACryptoServiceProvider.Create( "RSA" );
rsa.ImportParameters(parameter); byte [] result = rsa.EncryptValue(Encoding.UTF8.GetBytes( "PASSWORD" ));
//把密文轉化為HEX形式 string resultHex = BitConverter.ToString(result).Replace( "-" , "" );
|
對不起要無情的打擊你了,這麼做行不通,因為C#的RSA加密不是標準RSA,為了加強安全性,它強制使用了PKCS1填充(或OAEP填充),導致密文在Java端解密失敗,因為Java端用的是無填充模式(RSA/ECB/NoPadding)。
怎麼辦? 自己實現標準RSA加密吧。modulus和publicExponent都有了,再加上密碼,都轉化成大整數,做一個ModPow操作,就得到結果密文了。正好.NetFramework從4.0起在System.Numerics名稱空間下直接提供BigInterger類了,上手試試:
1
2
3
4
5
6
7
8
9
10
11
12
|
/*********** C#程式碼 ***********/ //把3個變數轉化為System.Numerics.BigInteger var modulus = new BigInteger(modulusBytes);
var exponent = new BigInteger(exponentBytes);
var data = new BigInteger(Encoding.UTF8.GetBytes( "PASSWORD" ));
//做ModPow運算得到密文,也是BigInteger var result = BigInteger.ModPow(data, exponent, modulus);
//把密文BigInteger對應的byte[]轉化為HEX形式 string resultHex = BitConverter.ToString(result.ToByteArray()).Replace( "-" , "" );
|
OH MY GOD!!! 還是不行,為什麼?
是位元組序在搗亂,我們上面分析ASN.1結構時得到的所有資料都是大位元組序的,而System.Numerics.BigInteger是小位元組序的,需要轉化之後才能使用。這點很煩人,要轉來轉去的。
1
2
3
4
5
6
7
8
9
10
11
12
|
/*********** C#程式碼 ***********/ //把3個變數轉化為System.Numerics.BigInteger var modulus = new BigInteger(modulusBytes.Reverse().ToArray());
var exponent = new BigInteger(exponentBytes.Reverse().ToArray());
var data = new BigInteger(Encoding.UTF8.GetBytes( "PASSWORD" ).Reverse().ToArray());
//做ModPow運算得到密文,也是BigInteger var result = BigInteger.ModPow(d, e, m);
//把密文BigInteger對應的byte[]轉化為HEX形式 string resultHex = BitConverter.ToString(result.ToByteArray().Reverse().ToArray()).Replace( "-" , "" );
|
再試一下,這下終於OK了。
問題完美解決了嗎? 很遺憾,沒有,因為System.Numerics.BigInteger是4.0以上版本才提供的,低於此版本的只好去使用第三方的實現,比如這個:http://www.codeproject.com/Articles/2728/Csharp-BigInteger-Class,但要注意以下2點:
1、它預設只支援560bit,程式碼最開頭有寫:private const int maxLength = 70;
把maxLength改成256才能支援2048位的RSA運算了。
2、它是大位元組序的,在使用時不用反轉modulus和publicExponent對應的byte[]。
3、我們得到的modulus是257個位元組,需要去掉首位元組的0,用剩下的256個位元組例項化BigInteger。
好,至此問題算是告一段落了,實測通過。以後想起來什麼再繼續補充吧。
我沒有提供完整解決方案的程式碼,只給出了部分程式碼片斷,希望對此問題有興趣的同學把重點放在理解過程上,而不是僅僅搬程式碼。
本文轉自 BoyTNT 51CTO部落格,原文連結:http://blog.51cto.com/boytnt/1351207,如需轉載請自行聯絡原作者
相關文章
- JAVA/PHP/C#版RSA驗籤JavaPHPC#
- C#和JAVA的RSA金鑰、公鑰轉換C#Java
- 10:c# mds5與des與rsa加密C#加密
- C# RSA 加密C#加密
- C#通過java生成的RSA公鑰加密和解密C#Java加密解密
- java/php/c#版rsa簽名以及java驗籤實現JavaPHPC#
- java RSA 解密Java解密
- security.js RSA加密與java客戶端解密JS加密Java客戶端解密
- RSA加密與解密加密解密
- java字串“==”與“equals”的差異及與c#的區別Java字串C#
- python中rsa的RSAPython
- Java之RSA加解密解析Java解密
- Android、Java RSA加密踩坑記AndroidJava加密
- RSA演算法原理——(3)RSA加解密過程及公式論證演算法解密公式
- 10 建立SSL與RSA證書與金鑰
- Java實現AES和RSA演算法Java演算法
- RSA演算法與Python實現演算法Python
- 洞見RSA 2021|零信任的困境與破局之路
- 十二載變與不變,綠盟科技的RSA之路
- 前後端java+vue 實現rsa 加解密與摘要簽名演算法後端JavaVue解密演算法
- 詳解Java Chassis 3與Spring Cloud的互操作JavaSpringCloud
- .net與C#的區別C#
- 微信支付 V3 RSA 加簽踩坑
- Java RSA (SHA1withRSA)簽名和驗籤Java
- 夢的開始——RSA
- RSA加密遇到的坑加密
- 26.RSA加密解密在Java專案中的簡單應用加密解密Java
- 淺談 C# Assembly 與 IL (一):C# Assembly 與 ReflectionC#
- Go與C#的比較 - RedditGoC#
- RSA加密加密
- C#學習筆記(與Java、C、C++和Python對比)C#筆記JavaC++Python
- RSA簽名的PSS模式模式
- C#之Equals與==C#
- 用c#建立與資料庫的連線 c#連sqlserverC#資料庫SQLServer
- RSA 2019觀察: 應用安全趨勢與解析 —— DevOPS與API安全devAPI
- 2010年RSA大會RSA總裁主題演講:雲的安全
- C#陣列與集合的區別C#陣列
- python (3.x) 實現RSA 加簽 驗籤 以及key的序列化Python
- C#基於RSA加密演算法實現軟體註冊實戰演練C#加密演算法