英文:
How to decode data encrypted using AES-256 in CBC mode and PKCS7 padding?
问题
以下是翻译好的内容:
我们正在使用以下Java代码来解密使用AES-256在CBC模式下加密并使用PKCS7填充的数据。
Java代码:
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import java.security.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
public class AES256 {
private static byte[] initVector = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public String decrypt(String encryptedDataBase64, String keyBase64) {
try {
Security.setProperty("crypto.policy", "unlimited");
IvParameterSpec ivSpec = new IvParameterSpec(initVector); // 获取初始化向量
// 获取Base64编码的密钥
byte[] key = Base64.decodeBase64(keyBase64.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); // AES / CBC / PKCS5填充
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
byte[] encryptedData = Base64.decodeBase64(encryptedDataBase64.getBytes("UTF-8"));
byte[] decryptedData = cipher.doFinal(encryptedData);
return new String(decryptedData);
} catch (Exception e) {
logger.error("AES256 Decrypt: 解密异常:" + e.getMessage());
return null;
}
}
}
现在我们需要将这个解密逻辑转换成JavaScript,因为我们的应用在请求index.html时会将加密数据发送到服务器的标头中。我尝试使用Crypto.js进行解密,但是解码后的字符串为空。以下是我尝试使用的JavaScript代码:
var key = CryptoJS.enc.Base64.parse(keyBase64);
var data = CryptoJS.enc.Base64.parse(encryptedDataBase64);
var dec_data = CryptoJS.AES.decrypt(data, key);
dec_data为空。
我在阅读了一些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:
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import java.security.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
public class AES256 {
private static byte[] initVector = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public String decrypt (String encryptedDataBase64, String keyBase64)
{
try {
Security.setProperty("crypto.policy", "unlimited");
IvParameterSpec ivSpec = new IvParameterSpec(initVector); // Get the init vector
// Get the Base64-encoded key
byte[] key = Base64.decodeBase64(keyBase64.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); // AES / CBC / PKCS5 padding
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
byte[] encryptedData = Base64.decodeBase64(encryptedDataBase64.getBytes("UTF-8"));
byte[] decryptedData = cipher.doFinal(encryptedData);
return new String(decryptedData);
}
catch (Exception e) {
logger.error("AES256 Decrypt: Decryption exception: "+ e.getMessage());
return null;
}
}
}
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.
var key = CryptoJS.enc.Base64.parse(keyBase64);
var data = CryptoJS.enc.Base64.parse(encryptedDataBase64);
var dec_data = CryptoJS.AES.decrypt(data, key);
dec_data is coming as empty.
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
以下是您提供的内容的翻译部分:
很遗憾,您没有提供任何示例数据来测试您的环境,因此我设置了自己的值。使用这些值:
ciphertext = rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz
keyBase64 = MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
ivBase = AAAAAAAAAAAAAAAAAAAAAA==
在 Java 中,我得到了这个解密结果:
The quick brown fox jumps over the lazy dog
在 JavaScript 端,我使用我的代码获得了相同的结果:
decrypted (str): The quick brown fox jumps over the lazy dog
您可以在这里进行实时测试 - Java: https://paiza.io/projects/e/dHG73CRgJojOOfLxtvJjtg 和 JavaScript: https://playcode.io/672463。
**请注意,我的代码没有异常处理,仅用于教育目的。此外 - 您的代码不安全,因为它使用了静态(固定)密钥和初始化向量。**
Java 代码(稍作更改,因为我使用了 Java 11 内置的 Base64 编码器):
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Base64;
public class Main {
private static byte[] initVector = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public static void main(String[] args) throws UnsupportedEncodingException {
System.out.println("如何解码使用 AES-256 在 CBC 模式和 PKCS7 填充下加密的数据");
String plaintext = "The quick brown fox jumps over the lazy dog";
byte[] key = "12345678901234567890123456789012".getBytes("UTF-8");
String keyBase64 = Base64.getEncoder().encodeToString(key);
System.out.println("keyBase64: " + keyBase64);
String ivBase64 = Base64.getEncoder().encodeToString(initVector);
System.out.println("initVector: " + ivBase64);
String ciphertext = "rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz";
System.out.println("ciphertext: " + ciphertext);
String decryptedtext = decrypt(ciphertext, Base64.getEncoder().encodeToString(key));
System.out.println("decryptedtext: " + decryptedtext);
}
public static String decrypt (String encryptedDataBase64, String keyBase64)
{
try {
Security.setProperty("crypto.policy", "unlimited");
IvParameterSpec ivSpec = new IvParameterSpec(initVector); // 获取初始化向量
byte[] key = Base64.getDecoder().decode(keyBase64.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); // AES / CBC / PKCS5 填充
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
byte[] encryptedData = Base64.getDecoder().decode(encryptedDataBase64.getBytes("UTF-8"));
byte[] decryptedData = cipher.doFinal(encryptedData);
return new String(decryptedData);
}
catch (Exception e) {
System.out.println("AES256 解密:解密异常:" + e.getMessage());
return null;
}
}
}
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());
<details>
<summary>英文:</summary>
Unfortunately you didn't provide any sample data to test with your environment so I setup my own values. Using this values:
ciphertext = rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz
keyBase64 = MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
ivBase = AAAAAAAAAAAAAAAAAAAAAA==
I'm getting this decrypt-result on Java:
The quick brown fox jumps over the lazy dog
On Javascript-side I receive the same results with my code:
decrypted (str): The quick brown fox jumps over the lazy dog
A live test can be done here - Java: https://paiza.io/projects/e/dHG73CRgJojOOfLxtvJjtg and Javascript: https://playcode.io/672463.
**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.**
Java code (slightly changed as I'm using the Java 11 built in Base64 encoder):
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Base64;
public class Main {
private static byte[] initVector = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
public static void main(String[] args) throws UnsupportedEncodingException {
System.out.println("How to decode data encrypted using AES-256 in CBC mode and PKCS7 padding");
String plaintext = "The quick brown fox jumps over the lazy dog";
byte[] key = "12345678901234567890123456789012".getBytes("UTF-8");
String keyBase64 = Base64.getEncoder().encodeToString(key);
System.out.println("keyBase64: " + keyBase64);
String ivBase64 = Base64.getEncoder().encodeToString(initVector);
System.out.println("initVector: " + ivBase64);
String ciphertext = "rjygE0TjIqiQ4ETnpszoieRWzaSD+9oINf1c748VcL/3zD5AazSFomx4paeanihz";
System.out.println("ciphertext: " + ciphertext);
String decryptedtext = decrypt(ciphertext, Base64.getEncoder().encodeToString(key));
System.out.println("decryptedtext: " + decryptedtext);
}
public static String decrypt (String encryptedDataBase64, String keyBase64)
{
try {
Security.setProperty("crypto.policy", "unlimited");
IvParameterSpec ivSpec = new IvParameterSpec(initVector); // Get the init vector
// Get the Base64-encoded key
byte[] key = Base64.getDecoder().decode(keyBase64.getBytes("UTF-8"));
//byte[] key = Base64.decodeBase64(keyBase64.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); // AES / CBC / PKCS5 padding
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
byte[] encryptedData = Base64.getDecoder().decode(encryptedDataBase64.getBytes("UTF-8"));
//byte[] encryptedData = Base64.decodeBase64(encryptedDataBase64.getBytes("UTF-8"));
byte[] decryptedData = cipher.doFinal(encryptedData);
return new String(decryptedData);
}
catch (Exception e) {
System.out.println("AES256 Decrypt: Decryption exception: "+ e.getMessage());
//logger.error("AES256 Decrypt: Decryption exception: "+ e.getMessage());
return null;
}
}
}
Javascript code:
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());
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论