如何解密使用AES-256在CBC模式下以及使用PKCS7填充方式加密的数据?

huangapple go评论111阅读模式
英文:

How to decode data encrypted using AES-256 in CBC mode and PKCS7 padding?

问题

以下是翻译好的内容:

我们正在使用以下Java代码来解密使用AES-256在CBC模式下加密并使用PKCS7填充的数据。

Java代码:

  1. import javax.crypto.spec.SecretKeySpec;
  2. import javax.crypto.Cipher;
  3. import javax.crypto.spec.IvParameterSpec;
  4. import java.security.*;
  5. import org.apache.commons.codec.binary.Base64;
  6. import org.apache.commons.lang.StringUtils;
  7. import org.apache.log4j.Logger;
  8. public class AES256 {
  9. private static byte[] initVector = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  10. public String decrypt(String encryptedDataBase64, String keyBase64) {
  11. try {
  12. Security.setProperty("crypto.policy", "unlimited");
  13. IvParameterSpec ivSpec = new IvParameterSpec(initVector); // 获取初始化向量
  14. // 获取Base64编码的密钥
  15. byte[] key = Base64.decodeBase64(keyBase64.getBytes("UTF-8"));
  16. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); // AES / CBC / PKCS5填充
  17. SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
  18. cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
  19. byte[] encryptedData = Base64.decodeBase64(encryptedDataBase64.getBytes("UTF-8"));
  20. byte[] decryptedData = cipher.doFinal(encryptedData);
  21. return new String(decryptedData);
  22. } catch (Exception e) {
  23. logger.error("AES256 Decrypt: 解密异常:" + e.getMessage());
  24. return null;
  25. }
  26. }
  27. }

现在我们需要将这个解密逻辑转换成JavaScript,因为我们的应用在请求index.html时会将加密数据发送到服务器的标头中。我尝试使用Crypto.js进行解密,但是解码后的字符串为空。以下是我尝试使用的JavaScript代码:

  1. var key = CryptoJS.enc.Base64.parse(keyBase64);
  2. var data = CryptoJS.enc.Base64.parse(encryptedDataBase64);
  3. var dec_data = CryptoJS.AES.decrypt(data, key);
  4. dec_data为空

如何解密使用AES-256在CBC模式下以及使用PKCS7填充方式加密的数据?

我在阅读了一些Stack Overflow的问题后尝试了这个。请问是否代码中有任何错误。

英文:

We are using below java code to decrypt the data which is encrypted using AES-256 in CBC mode and PKCS7 padding.

Java Code:

  1. import javax.crypto.spec.SecretKeySpec;
  2. import javax.crypto.Cipher;
  3. import javax.crypto.spec.IvParameterSpec;
  4. import java.security.*;
  5. import org.apache.commons.codec.binary.Base64;
  6. import org.apache.commons.lang.StringUtils;
  7. import org.apache.log4j.Logger;
  8. public class AES256 {
  9. private static byte[] initVector = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  10. public String decrypt (String encryptedDataBase64, String keyBase64)
  11. {
  12. try {
  13. Security.setProperty("crypto.policy", "unlimited");
  14. IvParameterSpec ivSpec = new IvParameterSpec(initVector); // Get the init vector
  15. // Get the Base64-encoded key
  16. byte[] key = Base64.decodeBase64(keyBase64.getBytes("UTF-8"));
  17. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); // AES / CBC / PKCS5 padding
  18. SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
  19. cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
  20. byte[] encryptedData = Base64.decodeBase64(encryptedDataBase64.getBytes("UTF-8"));
  21. byte[] decryptedData = cipher.doFinal(encryptedData);
  22. return new String(decryptedData);
  23. }
  24. catch (Exception e) {
  25. logger.error("AES256 Decrypt: Decryption exception: "+ e.getMessage());
  26. return null;
  27. }
  28. }
  29. }

Now we need to convert this decryption logic to Javascript as our app is sending the encrypted data in the headers while requesting for index.html from server. I tried to decrypt using Crypto.js but I am getting decoded string as empty. Below is the Javascript code I was trying to use.

  1. var key = CryptoJS.enc.Base64.parse(keyBase64);
  2. var data = CryptoJS.enc.Base64.parse(encryptedDataBase64);
  3. var dec_data = CryptoJS.AES.decrypt(data, key);

dec_data is coming as empty.

如何解密使用AES-256在CBC模式下以及使用PKCS7填充方式加密的数据?

I tried this after reading some of stack over flow questions. Can any one please let me know if there is any error in the code.

答案1

得分: 2

以下是您提供的内容的翻译部分:

  1. 很遗憾,您没有提供任何示例数据来测试您的环境,因此我设置了自己的值。使用这些值:
  2. ciphertext = rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz
  3. keyBase64 = MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
  4. ivBase = AAAAAAAAAAAAAAAAAAAAAA==
  5. Java 中,我得到了这个解密结果:
  6. The quick brown fox jumps over the lazy dog
  7. JavaScript 端,我使用我的代码获得了相同的结果:
  8. decrypted (str): The quick brown fox jumps over the lazy dog
  9. 您可以在这里进行实时测试 - Java: https://paiza.io/projects/e/dHG73CRgJojOOfLxtvJjtg 和 JavaScript: https://playcode.io/672463。
  10. **请注意,我的代码没有异常处理,仅用于教育目的。此外 - 您的代码不安全,因为它使用了静态(固定)密钥和初始化向量。**
  11. Java 代码(稍作更改,因为我使用了 Java 11 内置的 Base64 编码器):
  12. import javax.crypto.Cipher;
  13. import javax.crypto.spec.IvParameterSpec;
  14. import javax.crypto.spec.SecretKeySpec;
  15. import java.io.UnsupportedEncodingException;
  16. import java.security.Security;
  17. import java.util.Base64;
  18. public class Main {
  19. private static byte[] initVector = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  20. public static void main(String[] args) throws UnsupportedEncodingException {
  21. System.out.println("如何解码使用 AES-256 在 CBC 模式和 PKCS7 填充下加密的数据");
  22. String plaintext = "The quick brown fox jumps over the lazy dog";
  23. byte[] key = "12345678901234567890123456789012".getBytes("UTF-8");
  24. String keyBase64 = Base64.getEncoder().encodeToString(key);
  25. System.out.println("keyBase64: " + keyBase64);
  26. String ivBase64 = Base64.getEncoder().encodeToString(initVector);
  27. System.out.println("initVector: " + ivBase64);
  28. String ciphertext = "rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz";
  29. System.out.println("ciphertext: " + ciphertext);
  30. String decryptedtext = decrypt(ciphertext, Base64.getEncoder().encodeToString(key));
  31. System.out.println("decryptedtext: " + decryptedtext);
  32. }
  33. public static String decrypt (String encryptedDataBase64, String keyBase64)
  34. {
  35. try {
  36. Security.setProperty("crypto.policy", "unlimited");
  37. IvParameterSpec ivSpec = new IvParameterSpec(initVector); // 获取初始化向量
  38. byte[] key = Base64.getDecoder().decode(keyBase64.getBytes("UTF-8"));
  39. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); // AES / CBC / PKCS5 填充
  40. SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
  41. cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
  42. byte[] encryptedData = Base64.getDecoder().decode(encryptedDataBase64.getBytes("UTF-8"));
  43. byte[] decryptedData = cipher.doFinal(encryptedData);
  44. return new String(decryptedData);
  45. }
  46. catch (Exception e) {
  47. System.out.println("AES256 解密:解密异常:" + e.getMessage());
  48. return null;
  49. }
  50. }
  51. }

JavaScript 代码:

let keyBase64 = 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=';
let ivBase64 = 'AAAAAAAAAAAAAAAAAAAAAA==';
let iv = CryptoJS.enc.Base64.parse(ivBase64);
let secret_key = CryptoJS.enc.Base64.parse(keyBase64);
ciphertext = 'rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz';
console.log('ciphertext: ', ciphertext);
var decrypted = CryptoJS.AES.decrypt(ciphertext, secret_key,{
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC,
});
console.log('decrypted (str): ', CryptoJS.enc.Utf8.stringify(decrypted).toString());

  1. <details>
  2. <summary>英文:</summary>
  3. Unfortunately you didn&#39;t provide any sample data to test with your environment so I setup my own values. Using this values:
  4. ciphertext = rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz
  5. keyBase64 = MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
  6. ivBase = AAAAAAAAAAAAAAAAAAAAAA==
  7. I&#39;m getting this decrypt-result on Java:
  8. The quick brown fox jumps over the lazy dog
  9. On Javascript-side I receive the same results with my code:
  10. decrypted (str): The quick brown fox jumps over the lazy dog
  11. A live test can be done here - Java: https://paiza.io/projects/e/dHG73CRgJojOOfLxtvJjtg and Javascript: https://playcode.io/672463.
  12. **Please note that my code has no exception handling and is for educational purpose only. Additionally - your code is UNSECURE as it uses a static (fixed) key and initialization vector.**
  13. Java code (slightly changed as I&#39;m using the Java 11 built in Base64 encoder):
  14. import javax.crypto.Cipher;
  15. import javax.crypto.spec.IvParameterSpec;
  16. import javax.crypto.spec.SecretKeySpec;
  17. import java.io.UnsupportedEncodingException;
  18. import java.security.Security;
  19. import java.util.Base64;
  20. public class Main {
  21. private static byte[] initVector = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  22. public static void main(String[] args) throws UnsupportedEncodingException {
  23. System.out.println(&quot;How to decode data encrypted using AES-256 in CBC mode and PKCS7 padding&quot;);
  24. String plaintext = &quot;The quick brown fox jumps over the lazy dog&quot;;
  25. byte[] key = &quot;12345678901234567890123456789012&quot;.getBytes(&quot;UTF-8&quot;);
  26. String keyBase64 = Base64.getEncoder().encodeToString(key);
  27. System.out.println(&quot;keyBase64: &quot; + keyBase64);
  28. String ivBase64 = Base64.getEncoder().encodeToString(initVector);
  29. System.out.println(&quot;initVector: &quot; + ivBase64);
  30. String ciphertext = &quot;rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz&quot;;
  31. System.out.println(&quot;ciphertext: &quot; + ciphertext);
  32. String decryptedtext = decrypt(ciphertext, Base64.getEncoder().encodeToString(key));
  33. System.out.println(&quot;decryptedtext: &quot; + decryptedtext);
  34. }
  35. public static String decrypt (String encryptedDataBase64, String keyBase64)
  36. {
  37. try {
  38. Security.setProperty(&quot;crypto.policy&quot;, &quot;unlimited&quot;);
  39. IvParameterSpec ivSpec = new IvParameterSpec(initVector); // Get the init vector
  40. // Get the Base64-encoded key
  41. byte[] key = Base64.getDecoder().decode(keyBase64.getBytes(&quot;UTF-8&quot;));
  42. //byte[] key = Base64.decodeBase64(keyBase64.getBytes(&quot;UTF-8&quot;));
  43. Cipher cipher = Cipher.getInstance(&quot;AES/CBC/PKCS5PADDING&quot;); // AES / CBC / PKCS5 padding
  44. SecretKeySpec skeySpec = new SecretKeySpec(key, &quot;AES&quot;);
  45. cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
  46. byte[] encryptedData = Base64.getDecoder().decode(encryptedDataBase64.getBytes(&quot;UTF-8&quot;));
  47. //byte[] encryptedData = Base64.decodeBase64(encryptedDataBase64.getBytes(&quot;UTF-8&quot;));
  48. byte[] decryptedData = cipher.doFinal(encryptedData);
  49. return new String(decryptedData);
  50. }
  51. catch (Exception e) {
  52. System.out.println(&quot;AES256 Decrypt: Decryption exception: &quot;+ e.getMessage());
  53. //logger.error(&quot;AES256 Decrypt: Decryption exception: &quot;+ e.getMessage());
  54. return null;
  55. }
  56. }
  57. }
  58. Javascript code:
  59. let keyBase64 = &#39;MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=&#39;;
  60. let ivBase64 = &#39;AAAAAAAAAAAAAAAAAAAAAA==&#39;;
  61. let iv = CryptoJS.enc.Base64.parse(ivBase64);
  62. let secret_key = CryptoJS.enc.Base64.parse(keyBase64);
  63. ciphertext = &#39;rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz&#39;;
  64. console.log(&#39;ciphertext: &#39;, ciphertext);
  65. var decrypted = CryptoJS.AES.decrypt(ciphertext, secret_key,{
  66. iv: iv,
  67. padding: CryptoJS.pad.Pkcs7,
  68. mode: CryptoJS.mode.CBC,
  69. });
  70. console.log(&#39;decrypted (str): &#39;, CryptoJS.enc.Utf8.stringify(decrypted).toString());
  71. </details>

huangapple
  • 本文由 发表于 2020年9月17日 07:14:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/63929125.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定