2014-03-30 102 views
3

我有一個字符串。用java加密。現在我不得不用c解密它。如何在c sharp中解密「用java加密的字符串」?

我在c sharp和java中使用具有相同公鑰/私鑰的RSA算法。

但是在用c sharp解密的時候,我得到了一個「Bad Data」錯誤。

並且一個重要的通知是:我可以在java中解密這個字符串!我可以用c sharp加密並用c sharp解密!但是當我嘗試使用其中一個(c sharp或java)進行加密並使用另一個進行解密時,它會引發錯誤!

這是我的C代碼犀利:

string privateKey = "<RSAKeyValue><Modulus>rFsMn+idg8jmVMk249DzJc7AFft3+/jcnYDTh9wHee3tgFu1gBRh7e+ao+MWq7NEN0N7kUHa7O4c/ND2Ahcx/h4mXD5KDoixFRBUsxYqCJVA68qYJ7vozVPMjNr4jeOo1xt+oevO5+mUWtcaib5Iw51u1Jq/6qCqLsm8Eq3cnsE=</Modulus><Exponent>AQAB</Exponent><P>5aqTyz3GH655H+vO/BzJvFzpILpxLwXZEvqp3l3NYXKqP0tdkY1g36o6M9YodI3h8ho4VFYofIqA1+V0qPkuDQ==</P><Q>wB45uljBS8Z+WGRE1cRdpZb5aKUv76uLlCp6agtPBBhjXNIQrN8MpOCTvZM2cOsuYpYhDtnwsTY9KKXdBmv6hQ==</Q><DP>KB474uzPhwk7L1BJv9BnjPfN4WGwE765xI70zVslXThidNv9ZEeF/IwHzrZCKtn99gSOgmzqdZbcGtqCHmIooQ==</DP><DQ>eLnFrvsdJJ/sP2Fq/CX0bx0rR34eXG6hPI9g84h9s+YbcnWy8t8LVASn8oYyvMydDminB20e2k1qK0PnW6S4/Q==</DQ><InverseQ>rlPpLse8LJ0KRglnu2D1xzJT90QqzS3o80P0WTpUvm95mF5d8YaVj/d9W7FBdgZ98y6Q7of+wLCmYGKLg56wYQ==</InverseQ><D>Gs8mzZDPP3p2aWXLBfCwgYcBVeoBpc318wHg5VcSSqL5uGeLedqxyOLmOOvP0PFXgQkcJWIK/aOkGqcePQECo3TNiK+uLSwc97V3spZah70FFJVyh23Y+o0wlRGHAm5Nj9QieHlVwhgJPkNUJYgH9qkwB9aCpl+rdAG3da2fQ2E=</D></RSAKeyValue>"; 
string publicKey = "<RSAKeyValue><Modulus>rFsMn+idg8jmVMk249DzJc7AFft3+/jcnYDTh9wHee3tgFu1gBRh7e+ao+MWq7NEN0N7kUHa7O4c/ND2Ahcx/h4mXD5KDoixFRBUsxYqCJVA68qYJ7vozVPMjNr4jeOo1xt+oevO5+mUWtcaib5Iw51u1Jq/6qCqLsm8Eq3cnsE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"; 



public string EncryptData(string data2Encrypt) 
{ 
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
    rsa.FromXmlString(publicKey); 
    byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(data2Encrypt); 
    byte[] cipherbytes = rsa.Encrypt(plainbytes, false); 
    return Convert.ToBase64String(cipherbytes); 
} 

public string DecryptData(string data2Decrypt) 
{ 
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
    rsa.FromXmlString(privateKey); 
    byte[] plainbytes = rsa.Decrypt(Convert.FromBase64String(data2Decrypt), false); 
    return System.Text.Encoding.UTF8.GetString(plainbytes); 
} 

和我的Java代碼:

byte[] expBytes = Base64.decode("AQAB".getBytes("UTF-8"), Base64.DEFAULT); 
byte[] modBytes = Base64.decode("rFsMn+idg8jmVMk249DzJc7AFft3+/jcnYDTh9wHee3tgFu1gBRh7e+ao+MWq7NEN0N7kUHa7O4c/ND2Ahcx/h4mXD5KDoixFRBUsxYqCJVA68qYJ7vozVPMjNr4jeOo1xt+oevO5+mUWtcaib5Iw51u1Jq/6qCqLsm8Eq3cnsE=".getBytes("UTF-8"), Base64.DEFAULT); 
byte[] dBytes = Base64.decode("Gs8mzZDPP3p2aWXLBfCwgYcBVeoBpc318wHg5VcSSqL5uGeLedqxyOLmOOvP0PFXgQkcJWIK/aOkGqcePQECo3TNiK+uLSwc97V3spZah70FFJVyh23Y+o0wlRGHAm5Nj9QieHlVwhgJPkNUJYgH9qkwB9aCpl+rdAG3da2fQ2E=".getBytes("UTF-8"), Base64.DEFAULT); 

BigInteger modules = new BigInteger(1, modBytes); 
BigInteger exponent = new BigInteger(1, expBytes); 
BigInteger d = new BigInteger(1, dBytes); 

KeyFactory factory = KeyFactory.getInstance("RSA"); 
Cipher cipher = Cipher.getInstance("RSA"); 
String input = "test"; 

RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(modules, exponent); 
PublicKey pubKey = factory.generatePublic(pubSpec); 
cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
byte[] encrypted = cipher.doFinal(input.getBytes()); 

String strEncrypted = Base64.encodeToString(encrypted, Base64.DEFAULT); 

我不能解碼在C尖銳strEncrypted值。

並且在java中的加密值與c sharp(相同的鍵和算法和數據)不同!!!

+1

首先,您是否在調試器中驗證了您的Base64方法獲得了相同的'byte []'值?哪個'Base64'是Java中的? – chrylis

+0

如何將密文從一個系統轉移到另一個系統?你的密文有多大? –

+0

@chrylis其實我正在使用** android.util.Base64 ** – Mehdi

回答

0

我發現它:)

我改變了這一行:

Cipher cipher = Cipher.getInstance("RSA"); 

到:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); 

它運作良好。但是誰知道這些有什麼不同?

2

RSACryptoServiceProvider.Encrypt(plainbytes, false)的第二個參數表示使用PKCS#1填充。 true用於OAEP填充。

在Java中,您使用的安全提供程序的地圖"RSA""RSA/ECB/NoPadding",這只是沒有任何填充的加密,因此加密結果始終是相同的。因此,需要指定"RSA/ECB/PKCS1Padding"以匹配C#行爲。

您應該始終指定模式和填充,否則安全提供程序將選擇它自己的默認值 - 並且每個提供程序的默認值可能會有所不同。