2012-12-17 33 views
0

我們在應用程序中實現了某種自動登錄,並在C#中解密了一些用java加密的東西。在C#中實現Java解密AES算法

基本上,Java應用程序會生成某種URL。當用戶點擊這個鏈接時,我需要驗證查詢字符串,如果它們匹配,讓用戶的跡象。

有人提供的Java代碼。我需要將相同的代碼轉換爲C#,因爲我的應用程序使用C#。當我在C#中完全實現它時,出現錯誤。

這裏是java的解密碼:

String vParameter= "ksyR31QsRcbeJoysNOsAGBHajLKWsT00wavt9LJYGOMRC8zc_vqrNOeOlGHKJHIt3sLmFhDVw_JZKr4JT0H3Jj7_Di9bKNw99qCzMOKCXYM="; //The string that nees to be decoded. 
byte[] encryptedV = Base64.decodeBase64(vParameter); 
String salt = 「jkjkyt4」; // the i parameter - user’s id 
String password = 「^[email protected]!a89mz+%5rT」; // application specific 
MessageDigest digester = MessageDigest.getInstance("SHA-1"); 
digester.update((salt + password).getBytes("UTF-8")); 
byte[] key = digester.digest(); 
SecretKeySpec secretKey = new SecretKeySpec(key, 2, 16, 「AES」); 
String appIV = "SampleIV"// application specific 
IvParameterSpec iv= new IvParameterSpec(appIV.getBytes(「UTF-8」)); 
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); 
byte[] decryptedV = cipher.doFinal(encryptedV, 0, encryptedV.length); 
String v = new String(decryptedV, 「UTF-8」); 

下面是相應的C#代碼

 string vParameter = "ksyR31QsRcbeJoysNOsAGBHajLKWsT00wavt9LJYGOMRC8zc_vqrNOeOlGHKJHIt3sLmFhDVw_JZKr4JT0H3Jj7_Di9bKNw99qCzMOKCXYM="; //v parameter 
     byte[] encryptedV = Encoding.UTF8.GetBytes(vParameter); 
     String salt = "jkjkyt4"; // the i parameter - user’s id 
     String password = "^[email protected]!a89mz+%5rT"; // application specific 
     var sha1 = SHA1Managed.Create(); 

     byte[] keyBytes = Encoding.UTF8.GetBytes(salt + password); //salt + password 
     byte[] key = sha1.ComputeHash(keyBytes); 
     byte[] finalKey = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; 
     String appIV = "SampleIV"; 
     byte[] iv = Encoding.UTF8.GetBytes(appIV); //iv 
     Array.Copy(key, 2, finalKey, 0, 16); //key 2, 16 
     AesManaged tdes = new AesManaged(); 
     tdes.Key = finalKey; 
     tdes.Mode = CipherMode.CBC; 
     tdes.Padding = PaddingMode.PKCS7; 
     tdes.IV = iv; 
     ICryptoTransform crypt = tdes.CreateDecryptor(); 
     byte[] cipher = crypt.TransformFinalBlock(encryptedV, 0, encryptedV.Length); 
     string decryptedText = Convert.ToBase64String(cipher); 
     return decryptedText; 

我在做什麼錯?任何人都可以指出錯誤嗎?

編輯:我更新了V參數...注 - 密鑰,密碼和IV是不是真實的。我不得不改變他們,因爲我不希望我的公司密鑰公開。

編輯2:嗨,我已經更新了vParameter ..現在他們是一樣的。 Java代碼正在工作......它已在另一個應用程序中實現。現在,我必須爲我的C#應用​​程序創建一個類似的版本。你們可以指出C#代碼中的任何問題嗎?

+2

有在Java代碼中的至少兩個錯誤:1)IV是不16個字節(讓a單獨的隨機字節)和2)密碼文本直接轉換爲字符串,並且不編碼有效字符的UTF-8編碼爲*丟失*。 –

+0

相反Encoding.UTF8.GetBytes的'()'嘗試,'Convert.FromBase64String()'的第一個'Base64.decodeBase64()'反正 –

+1

爲什麼不同的'vParameter'碼,如果密碼和IV是不?你會期望一個不同的純文本,有什麼用處呢? –

回答

3

您正在混合UTF8的en/decodings和base64 en/decodings。此外,由於密文和IV的長度不對,發佈的代碼不起作用。我懷疑這是因爲你改變了他們以避免泄露你的真實數據。

不管怎麼說,這是一個Java代碼段和返回相同結果的C#-snippet:

的Java(我只改vParameter和appIV到一些作品):

String vParameter= "Lq4aURUiyvKvEZBWMWpUr2wRSMu96E+J1UeHLTOhKEM="; //The string that needs to be decoded. 
byte[] encryptedV = Base64.decodeBase64(vParameter.getBytes("ASCII")); 
String salt = "jkjkyt4"; // the i parameter - user’s id 
String password = "^[email protected]!a89mz+%5rT"; // application specific 
MessageDigest digester = MessageDigest.getInstance("SHA-1"); 
digester.update((salt + password).getBytes("UTF-8")); 
byte[] key = digester.digest(); 
SecretKeySpec secretKey = new SecretKeySpec(key, 2, 16, "AES"); 
String appIV = "SampleIV12345678";// application specific 
IvParameterSpec iv= new IvParameterSpec(appIV.getBytes("UTF-8")); 
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); 
byte[] decryptedV = cipher.doFinal(encryptedV, 0, encryptedV.length); 
String v = new String(decryptedV, "UTF-8"); 
System.out.println(v); // foobarfoobarfoobarfoobarfoobar 

C#(使用的Base64解碼vParameter並解碼經解密的數據以UTF-8同樣重命名AES對象爲AES代替TDES):

string vParameter = "Lq4aURUiyvKvEZBWMWpUr2wRSMu96E+J1UeHLTOhKEM="; //v parameter 
byte[] encryptedV = Convert.FromBase64String(vParameter); 
string salt = "jkjkyt4"; // the i parameter - user’s id 
string password = "^[email protected]!a89mz+%5rT"; // application specific 
var sha1 = SHA1Managed.Create(); 
byte[] keyBytes = Encoding.UTF8.GetBytes(salt + password); //salt + password 
byte[] key = sha1.ComputeHash(keyBytes); 
byte[] finalKey = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; 
string appIV = "SampleIV12345678"; 
byte[] iv = Encoding.UTF8.GetBytes(appIV); //iv 
Array.Copy(key, 2, finalKey, 0, 16); //key 2, 16 
AesManaged aes = new AesManaged(); 
aes.Key = finalKey; 
aes.Mode = CipherMode.CBC; 
aes.Padding = PaddingMode.PKCS7; 
aes.IV = iv; 
ICryptoTransform crypt = aes.CreateDecryptor(); 
byte[] cipher = crypt.TransformFinalBlock(encryptedV, 0, encryptedV.Length); 
string decryptedText = Encoding.UTF8.GetString(cipher); 
Console.WriteLine(decryptedText); // foobarfoobarfoobarfoobarfoobar 
+0

嗨Rasmus Faber,謝謝你的幫助。我可以繼續前進,但我收到錯誤消息「填充無效,無法刪除。」在crypt.TransformFinalBlock函數... – InvisibleDev

+0

@InvisibleDev:你得到了我上面寫的確切代碼的填充錯誤,或者當你替換自己的值? –

+0

嗨Rasmus,它現在有效。 IV和Key是錯誤的。當我用正確的值替換它時,它現在可以工作。非常感謝您的幫助。 – InvisibleDev