由于几天我试图弄清楚为什么我在javascript(cryptojs)和java不同的加密输出。我处于死胡同,不知道该改变什么,我想我会失去理智。这是完整的代码,应该很容易复制粘贴进行测试。你是我最后的希望。 ^^
plainText = plaintext
password = password
salt = 3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55
iv = 3C46C00F42A6044A"
Javascript result = zbohHpV5RtmHiH3cKDY15w ==
Java结果= wVdRQiIqkyVlttkWpCMSpQ ==
Javascript html:已更新并将迭代更改为10
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Aes Test</title>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/pbkdf2.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
</head>
<body>
<div id="result"></div>
</body>
<script>
var password = "password";
var salt = "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55";
var plainText = "plaintext";
var iv = "3C46C00F42A6044A";
var key = CryptoJS.PBKDF2(password, CryptoJS.enc.Hex.parse(salt), {keySize: 128/32, iterations: 10});
var a = CryptoJS.AES.encrypt(plainText, key, {iv: CryptoJS.enc.Hex.parse(iv)}).ciphertext.toString(CryptoJS.enc.Base64);
var result = "encypted: " + a + "<br \>";
document.getElementById("result").innerHTML = result;
</script>
</html>
Java Main.class
public class main {
public static void main(String[] args) throws Exception {
String result = Aes.encrypt("plaintext", "password", "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55", "3C46C00F42A6044A");
System.out.println(result);
}
}
Java Aes.class
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Aes {
private static final int pswdIterations = 10;
private static final int keySize = 128;
public static String encrypt(String plainText, String password, String salt, String initializationVector) throws NoSuchAlgorithmException, InvalidKeySpecException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
byte[] saltBytes = salt.getBytes("UTF-8");
byte[] ivBytes = initializationVector.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, pswdIterations, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes));
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes());
return new Base64().encodeAsString(encryptedTextBytes);
}
}
答案 0 :(得分:1)
最后他们都是平等的,感谢pasimako把我带到路上。我不得不改变iv和salt转换为十六进制的方式以及iv的长度,如上所述,keySize和iterationCount变量也是未定义的。
这是完整的工作代码。
他们都应输出:
encypted:47S4kEkmEoMoOgngftzyFg ==
<强>的Javascript 强>
<script>
var password = "password";
var salt = "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55";
var plainText = "plaintext";
var iv = "12345678901234567890123456789012";
var key = CryptoJS.PBKDF2(password, CryptoJS.enc.Hex.parse(salt), {keySize: 128/32, iterations: 10});
var a = CryptoJS.AES.encrypt(plainText, key, {iv: CryptoJS.enc.Hex.parse(iv)}).ciphertext.toString(CryptoJS.enc.Base64);
var result = "encypted: " + a + "<br \>";
document.getElementById("result").innerHTML = result;
</script>
Java Main.class
public class main {
public static void main(String[] args) throws Exception {
String result = Aes.encrypt("plaintext", "password", "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55", "12345678901234567890123456789012");
System.out.println(result);
}
}
Java Aes.class
public class Aes {
private static final int pswdIterations = 10;
private static final int keySize = 128;
public static String encrypt(String plainText, String password, String salt, String initializationVector) throws NoSuchAlgorithmException, NoSuchPaddingException, DecoderException, InvalidKeySpecException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password.toCharArray(), Hex.decodeHex(salt.toCharArray()), pswdIterations, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(Hex.decodeHex(initializationVector.toCharArray())));
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes());
return new Base64().encodeAsString(encryptedTextBytes);
}
}
答案 1 :(得分:0)
首先,您的JavaScript代码是错误的。尝试下面的代码,看看你的keySize和iterationCount变量是未定义的。
Aes.generateKey = function(salt, passPhrase) {
console.log(this.keySize);
console.log(this.iterationCount);
var key = CryptoJS.PBKDF2(
passPhrase,
CryptoJS.enc.Hex.parse(salt),
{ keySize: this.keySize, iterations: this.iterationCount });
return key;
}
JavaScript的结果应该是Bttn5HNBIFDQ5hb1IbOFXQ ==
var password = "password";
var salt = "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55";
var plainText = "plaintext";
var iv = "3C46C00F42A6044A";
var key = CryptoJS.PBKDF2(password, CryptoJS.enc.Hex.parse(salt), {keySize: 128/32, iterations: 10000});
var a = CryptoJS.AES.encrypt(plainText, key, {iv: CryptoJS.enc.Hex.parse(iv)}).ciphertext.toString(CryptoJS.enc.Base64);
console.log(a);