2014-06-21 34 views
0

我們在嘗試加密Android中的數據並將其解密爲WCF服務時遇到問題。 Android的代碼來加密數據如下:使用RSA的Android中的加密方法中的密碼字節無效

try{ 
String strModulus = "tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZ/HG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U="; 
String strExponent = "AQAB"; 
byte[] modulusBytes = Base64.decode(strModulus, Base64.DEFAULT); 
byte[] exponentBytes = Base64.decode(strExponent, Base64.DEFAULT); 

BigInteger modulus = new BigInteger(1, modulusBytes);    
BigInteger exponent = new BigInteger(1, exponentBytes); 

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent); 
KeyFactory fact = KeyFactory.getInstance("RSA/ECB/PKCS1Padding"); 
PublicKey pubKey = fact.generatePublic(rsaPubKey);  

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
cipher.init(Cipher.ENCRYPT_MODE, pubKey); 

byte[] plainBytes = new String("Manchester United").getBytes("UTF-8"); 
byte[] cipherData = cipher.doFinal(plainBytes); 
encryptedString = Base64.encodeToString(cipherData, Base64.DEFAULT); 
} 
catch(Exception e){ 
Log.e("Error", e.toString()); 
} 

return encryptedString; 

相同的代碼在Java中:

try{ 
     String strModulus = "tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZHG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U="; 
     String strExponent = "AQAB"; 
     byte[] modulusBytes = DatatypeConverter.parseBase64Binary("tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZ/HG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U="); 
     byte[] exponentBytes = DatatypeConverter.parseBase64Binary("AQAB"); 

     BigInteger modulus = new BigInteger(1, modulusBytes); 
     BigInteger exponent = new BigInteger(1, exponentBytes); 

     RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent); 
     KeyFactory fact = KeyFactory.getInstance("RSA"); 
     PublicKey pubKey = fact.generatePublic(rsaPubKey); 

     Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, pubKey); 

     byte[] plainBytes = new String("Manchester United").getBytes("UTF-8"); 
     byte[] cipherData = cipher.doFinal(plainBytes); 
     //String encryptedString = Base64.encodeToString(cipherData, Base64.NO_PADDING); 
     String encryptedString = DatatypeConverter.printBase64Binary(cipherData); 
     String encryptedData = encryptedString; 
    } 
    catch(Exception e){ 
    }  
} 

WCF服務:

public string Decrypt() 
{ 
    const int PROVIDER_RSA_FULL = 1; 
    const string CONTAINER_NAME = "Tracker"; 
    CspParameters cspParams; 
    cspParams = new CspParameters(PROVIDER_RSA_FULL); 
    cspParams.KeyContainerName = CONTAINER_NAME; 
    RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(cspParams); 
    rsa1.FromXmlString("<RSAKeyValue><Modulus>tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZ/HG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U=</Modulus><Exponent>AQAB</Exponent><P>6e0nv7EBFBugtpoB+ozpg1J4js8E+DVyWCuBsERBPzqu4H7Z/oeLIRSC8Gi5GZgrCpBf3EvyIluM7rzaIfNThQ==</P><Q>x/29X9ns1WcXC42IJjLDjscz5ygdVh79dm8B2tQVbqwyhDsQ6OIOQdu5+eHf4hUMoTrM9KkS2F6FGlLXuaOFoQ==</Q><DP>kTS2LMaJ/dpce5zDx6w6s1q5HSSiWBSNIu/2s9zah448yXvUg6vNkD40PVk0NRAA/7C44H2AExWzOOqfmN17JQ==</DP><DQ>xtAx9drQPWnpl/uQUOEAVa0kpPTVDStrr9Q1FNTnpYkcAyYw7kLkB4anAIoSpk9kqdeprsNxz5VPXtbiTFMKYQ==</DQ><InverseQ>O0594NMjnjSp+/NAa1kQxoQNzn1qqq+p1Zb+kT3/jRc/0d7ZnqSSpxFMXfxx3yZkNAOPDOdbckPQbRZ13RKBHg==</InverseQ><D>bjVEagwvkrZaTt9CTW1hd3362weLFlX6DpE/3R3RcrpVfkSwKGpEhqGrNeeGPlsuqiaf5rAFir4eTqrF1QVliKsU4XE0RyzP5lHGc7dlX4DOHMjs2R9nNWv8QOTPoaRuLrLGorqBXlw/jQPxFI6gQzkIIjzuf//lDVnFam3dw4E=</D></RSAKeyValue>"); 
    string data2Decrypt = "LyVNDhkdJ5jNgwZDiVZ1R0lmd10AQgqNDFHh2vJB1676eg8wj0MOdTyChAGrvEjha0uXg+f/aNBAc4+/LFbCgsA1e+O3wnXr27sXznGJ9G15avZzQHG4JWUS42MXBahAkcJ80pcihTbL9edfQCkEuj9RzQ/zFJyDEMssfd/EPDM="; 
    byte[] encyrptedBytes = Convert.FromBase64String(data2Decrypt); 
    byte[] plain = rsa1.Decrypt(encyrptedBytes, false); 
    string decryptedString = System.Text.Encoding.UTF8.GetString(plain); 
} 

原始數據: '曼聯'

奇怪的是,如果我用Java代碼加密一個字符串,它可以在WCF服務端解密,howe ver,如果使用上面的Android代碼進行加密,則解密會提供錯誤:「要解密的數據超過128字節這個模數的最大值」。

在調試時,我意識到byte[] cipherData對於Android和Java來說是不一樣的。所有以前的值恰巧同步。這會在Java和Android中生成不同的加密字符串。

我的問題是爲什麼會發生這種情況?有一個愚蠢的錯誤?有沒有辦法解決它?或者其他可以在Android中完成「密碼數據」的權利?

任何幫助將不勝感激。

+0

PKCS#1填充包含隨機數據,因此如果您反覆加密相同的數據,您總會得到不同的結果。這不是你的WCF問題的原因。你可以共享你的WCF服務的代碼嗎?是否有可能在解密之前忘記base64解碼數據? –

+0

@Duncan WCF代碼已被添加。正如你在代碼中看到的,我已經在解密數據之前將代碼轉換爲base64。仍然不起作用。我不明白它如何在java代碼中完美地工作,而不是在android中。 –

回答

0

您正在Android上使用不同的填充。在Android上也使用完全相同的填充:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
+0

已經嘗試過,但仍然沒有工作。 –

+0

@RohitSonawane無論如何這是個好建議。總是在代碼中指定完整的轉換。你可能希望編輯你的問題代碼示例,以清楚表明你已經嘗試過。 –

+0

我的不好。我編輯了這篇文章。 –