簡體   English   中英

從 Java 轉換為 C# - 使用 PKCS5Padding 解密 CBC-AES-256

[英]Convert from Java to C# - Decrypt CBC-AES-256 with PKCS5Padding

我正在嘗試從 ClickBank 解密“即時通知”,他們有用於解碼多種語言的代碼示例,但不是 C#,所以我正在嘗試翻譯 Java 代碼: https : //support.clickbank.com/hc/en- us/articles/220376507-Instant-Notification-Service-INS-#Code%20Samples

在過去的幾天里,我嘗試了幾種不同的方法,但沒有運氣! 請幫助,我錯過了什么?

爪哇:

final StringBuilder buffer = new StringBuilder();
final String secretKey = "YOUR SECRET KEY";


String line;
final BufferedReader reader = theRequest.getReader();
while(null != (line = reader.readLine())) {
   buffer.append(line);
}


   final JSONParser parser = new JSONParser();
   final JSONObject obj = (JSONObject) parser.parse(buffer.toString()); 

   final String initializationVector = (String) obj.get("iv");
   final String encryptedNotification = (String) obj.get("notification"); 
   final MessageDigest digest = MessageDigest.getInstance("SHA-1");
   digest.reset();
   digest.update(secretKey.getBytes("UTF-8"));
   final String key = new String(Hex.encodeHex(digest.digest())).substring(0, 32);


   final IvParameterSpec iv = new IvParameterSpec(DatatypeConverter.parseBase64Binary(initializationVector));
   final SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
   final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
   cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);

   final JSONObject notification = (JSONObject) parser.parse(
   new String(cipher.doFinal(DatatypeConverter.parseBase64Binary(encryptedNotification)),
                 "ISO-8859-1"));`

C#

        const string secretKey = "YOUR SECRET KEY";
        string sContent = "";
        using (System.IO.Stream receiveStream = Request.InputStream)
        {
            receiveStream.Position = 0;
            using (System.IO.StreamReader readStream =
                   new System.IO.StreamReader(receiveStream, Encoding.UTF8))
            {
                sContent = readStream.ReadToEnd();
            }
        }
        dynamic json = System.Web.Helpers.Json.Decode(sContent);
        string initializationVector = json.iv;
        string encryptedNotification = json.notification;

        //turn the key into a fixed length string via SHA-1 hash
        SHA1 sha1 = SHA1Managed.Create();
        byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(secretKey));
        var key = Org.BouncyCastle.Utilities.Encoders.Hex.Encode(hash);
        var keyString = Convert.ToBase64String(key).Substring(0, 32);
        //var key = BitConverter.ToString(hash).Substring(0, 32);

        var iv = Convert.FromBase64String(initializationVector);
        byte[] keyspec = Encoding.UTF8.GetBytes(keyString);

         using (var rijndaelManaged =
               new RijndaelManaged { Key = keyspec, IV = iv, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 })
        using (var memoryStream =
               new MemoryStream(Convert.FromBase64String(encryptedNotification)))
        using (var cryptoStream =
               new CryptoStream(memoryStream,
                   rijndaelManaged.CreateDecryptor(keyspec, iv),
                   CryptoStreamMode.Read))
        {
            var result = new StreamReader(cryptoStream).ReadToEnd();
        }

給出錯誤 - “填充無效,無法刪除。”

所以我猜我一定是創建了錯誤的密鑰,我嘗試了不同的散列和十六進制編碼方式,但似乎都不起作用。 請各位大俠指教! 謝謝你的時間

編輯:刪除無用的額外代碼

哦,天哪,一家使用 CBC 發送消息的銀行。 這個 Java 代碼示例看起來像“我第一次嘗試加密”,並且來自銀行,這不是您應該信任的銀行。

密鑰確實是錯誤的,您應該嘗試key = Hex.ToHexString() ,然后使用Encoding.ASCII.GetBytes(key)將結果的子字符串轉換為 ASCII。 Java 代碼中不存在額外的 base 64 或位轉換,不應使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM