Java 使用 CryptoJS 进行 AES 加密
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41678504/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AES Encrypt using CryptoJS
提问by Sergio David Romero
I need to implement AES encryption using JavaScript. Used AES/CBC/NoPadding Mode and created a method to complete 16 lenght blocks. I already solved it using Java. It looks like:
我需要使用 JavaScript 实现 AES 加密。使用 AES/CBC/NoPadding 模式并创建了一种方法来完成 16 个长度块。我已经使用Java解决了它。看起来像:
public static String encrypt(byte[] key, byte[] initVector, String value) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(completeBlocks(value));
return Base64.encodeBase64String(encrypted);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException ex) {
System.out.println("Error: " + ex);
}
return null;
}
/**
* Completes 16 lenght blocks
*
* @param message
*
*
*/
static byte[] completeBlocks(String message) {
try {
int bytesLenght = message.getBytes("UTF-8").length;
if (bytesLenght % 16 != 0) {
byte[] newArray = new byte[bytesLenght + (16 - (bytesLenght % 16))];
System.arraycopy(message.getBytes(), 0, newArray, 0, bytesLenght);
return newArray;
}
return message.getBytes("UTF-8");
} catch (UnsupportedEncodingException ex) {
System.out.println("" + ex);
}
return null;
}
public static void main(String[] args) {
String key = "253D3FB468A0E24677C28A624BE0F939";
String strToEncrypt = "My Secret text";
final byte[] initVector = new byte[16];
String resultado = encrypt(new BigInteger(key, 16).toByteArray(), initVector, strToEncrypt.trim());
System.out.println("ENCRYPTED:");
System.out.println(resultado);
}
With inputs key = 253D3FB468A0E24677C28A624BE0F939
, strToEncrypt = "My Secret text"
and ceros IV. It throws
随着输入key = 253D3FB468A0E24677C28A624BE0F939
,strToEncrypt = "My Secret text"
和ceros IV。它抛出
7StScX3LnPUly/VNzBes0w==
7StScX3LnPUly/VNzBes0w==
I Know it's the desired output. It's right! I tried to replicate this using JavaScript. I used CryptoJs library. But i wasn't able to produce same Java's output. I have tryed:
我知道这是所需的输出。这是正确的!我尝试使用 JavaScript 复制它。我使用了 CryptoJs 库。但我无法产生相同的 Java 输出。我试过:
var text = "My Secret text";
var key = CryptoJS.enc.Base64.parse("253D3FB468A0E24677C28A624BE0F939");
var iv = CryptoJS.enc.Base64.parse(" ");
var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv});
console.log(encrypted.toString());
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {iv: iv});
console.log(decrypted.toString(CryptoJS.enc.Utf8));
Using the same inputs, i get De+CvPVIyiBX2//EE6gXTg==
as output. What am I doing wrong? How can i get same Java's output? Thanks a lot!!
使用相同的输入,我得到De+CvPVIyiBX2//EE6gXTg==
作为输出。我究竟做错了什么?如何获得相同的 Java 输出?非常感谢!!
采纳答案by Alex K.
Assuming you will fix things like the empty IV & that this is a proof of concept, your code fails because:
假设您将修复诸如空 IV 之类的问题,并且这是一个概念证明,那么您的代码将失败,因为:
- You use no padding in Java, you need to use the same in JS
- You manually pad with nulls in Java, you need to do the same in JS
- You base64 decode the key but its not base64 (its a hexadecimal string of bytes)
- The Java IV is an array of nulls but in JS you use whitespace (and erroneously treat it as base64).
- 您在 Java 中不使用填充,您需要在 JS 中使用相同的填充
- 您在 Java 中手动填充空值,您需要在 JS 中执行相同操作
- 你 base64 解码密钥,但它不是 base64(它是一个十六进制的字节串)
- Java IV 是一个空数组,但在 JS 中您使用空格(并错误地将其视为 base64)。
To duplicate the output in JS:
在 JS 中复制输出:
CryptoJS.pad.NoPadding = {pad: function(){}, unpad: function(){}};
var text = "My Secret text let iv = CryptoJS.lib.WordArray.random(IV_LENGTH);
const key = CryptoJS.enc.Utf8.parse(ENCRYPTION_KEY);
let encrypted = CryptoJS.AES.encrypt(text, key, { iv })
const encrypted = encrypted.iv+':'+encrypted.ciphertext
##代码##";
var key = CryptoJS.enc.Hex.parse("253D3FB468A0E24677C28A624BE0F939");
var iv = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");
var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv, padding: CryptoJS.pad.NoPadding});
console.log(encrypted.toString());
For:
为了:
7StScX3LnPUly/VNzBes0w==
7StScX3LnPUly/VNzBes0w==
回答by Sagar M
If you want to encrypt using custom IV, then you can encrypt like...
如果您想使用自定义 IV 进行加密,那么您可以像...
##代码##