2014-03-24 125 views
7

我正在制作一个需要基于Java的AES加密和基于JavaScript的解密的应用程序。 我正在使用以下代码进行加密,作为基本表单。使用Java进行AES加密并使用Javascript进行解密

public class AESencrp { 

    private static final String ALGO = "AES"; 
    private static final byte[] keyValue = 
     new byte[] { 'A', 'b', 'c', 'd', 'e', 'f', 'g', 
     'h', 'i', 'j', 'k','l', 'm', 'n', 'o', 'p'}; 

    public static String encrypt(String Data) throws Exception { 
    Key key = generateKey(); 
    Cipher c = Cipher.getInstance(ALGO); 
    c.init(Cipher.ENCRYPT_MODE, key); 
    byte[] encVal = c.doFinal(Data.getBytes()); 
    String encryptedValue = new BASE64Encoder().encode(encVal); 
    return encryptedValue; 
    } 


    private static Key generateKey() throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGO); 
    return key; 
    } 
} 

,我试图用解密JavaScript是

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"> </script> 

var decrypted = CryptoJS.AES.decrypt(encrypted,"Abcdefghijklmnop").toString(CryptoJS.enc.Utf8); 

但JavaScript的解密是行不通的。我对此很陌生,有人能告诉我一种解决方法,无需更改Java代码块吗?

我试过的Base-64解码我的文字是这样的:

var words = CryptoJS.enc.Base64.parse(encrKey); 
var base64 = CryptoJS.enc.Base64.stringify(words); 
var decrypted = CryptoJS.AES.decrypt(base64, "Abcdefghijklmnop"); 
alert("dec :" +decrypted); 

,但仍然没有好。

我尝试了下面建议的解决方案来解决可能的填充问题,但它没有给出任何解决方案。

var key = CryptoJS.enc.Base64.parse("QWJjZGVmZ2hpamtsbW5vcA=="); 
var decrypt = CryptoJS.AES.decrypt(encrKey, key, { mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7 }); 

alert("dec :" +decrypt); 
+0

“*但JavaScript解密不起作用*”>请您详细说明一下吗? –

+0

我的意思是页面在解密行停止执行,我想我试图解密它的方式有一些错误。 – rkj

+0

JavaScript控制台中是否显示错误?我的第一个猜测是,在你用CryptoJS解密密文之前,你还没有base64解密密文。请参阅https://code.google.com/p/crypto-js/#Encoders。 –

回答

9
  1. 你的Java代码使用128位的AES密钥,而你的JavaScript代码使用256位AES密钥。

  2. 你的Java代码中使用了“Abcdefghijklmnop” .getBytes()作为实际的密钥值,而你的JavaScript代码使用“Abcdefghijklmnop”作为从实际的密钥导出密码。

  3. Java AES的默认转换是AES/ECB/PKCS5Padding,而CryptoJS的默认转换是AES/CBC/PKCS7Padding。

一个解决您的例子方法是将JavaScript端修复:

// this is Base64 representation of the Java counterpart 
// byte[] keyValue = new byte[] { 'A', 'b', 'c', 'd', 'e', 'f', 'g', 
//    'h', 'i', 'j', 'k','l', 'm', 'n', 'o', 'p'}; 
// String keyForJS = new BASE64Encoder().encode(keyValue); 
var base64Key = "QWJjZGVmZ2hpamtsbW5vcA=="; 
console.log("base64Key = " + base64Key); 

// this is the actual key as a sequence of bytes 
var key = CryptoJS.enc.Base64.parse(base64Key); 
console.log("key = " + key); 

// this is the plain text 
var plaintText = "Hello, World!"; 
console.log("plaintText = " + plaintText); 

// this is Base64-encoded encrypted data 
var encryptedData = CryptoJS.AES.encrypt(plaintText, key, { 
    mode: CryptoJS.mode.ECB, 
    padding: CryptoJS.pad.Pkcs7 
}); 
console.log("encryptedData = " + encryptedData); 

// this is the decrypted data as a sequence of bytes 
var decryptedData = CryptoJS.AES.decrypt(encryptedData, key, { 
    mode: CryptoJS.mode.ECB, 
    padding: CryptoJS.pad.Pkcs7 
}); 
console.log("decryptedData = " + decryptedData); 

// this is the decrypted data as a string 
var decryptedText = decryptedData.toString(CryptoJS.enc.Utf8); 
console.log("decryptedText = " + decryptedText); 
+1

不,仍然没有工作。你确定你的“var解密”是正确的,因为我认为密钥应该是UTF-8格式。无论如何,我试过但没有工作。 – rkj

+0

您的问题现在包含'CryptoJS.AES.decrypt(encrKey,key,...)'末尾,似乎您正在尝试使用密钥解密密钥,这毫无意义。第一个参数应该是base64中的加密数据。 –

+0

这就是我所遵循的命名约定。第一个参数确实是加密的数据。 – rkj

0

对于Java和JavaScript能够相互操作,至关重要的是,没有使用缺省值在创建键或密码。迭代计数,密钥长度,填充,盐和IV应该都是相同的。

参考:https://github.com/mpetersen/aes-example

示例代码如下:Java中

加密字符串:

String keyValue = "Abcdefghijklmnop";  
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    KeySpec spec = new PBEKeySpec(keyValue.toCharArray(), hex("dc0da04af8fee58593442bf834b30739"), 
     1000, 128); 

    Key key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); 
    Cipher c = Cipher.getInstance(“AES/CBC/PKCS5Padding”); 
    c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(hex("dc0da04af8fee58593442bf834b30739"))); 

    byte[] encVal = c.doFinal("The Quick Brown Fox Jumped over the moon".getBytes()); 
    String base64EncodedEncryptedData = new String(Base64.encodeBase64(encVal)); 
    System.out.println(base64EncodedEncryptedData); 

}

解密JavaScript中的相同的字符串:

var iterationCount = 1000; 
var keySize = 128; 
var encryptionKey ="Abcdefghijklmnop"; 
var dataToDecrypt = "2DZqzpXzmCsKj4lfQY4d/exg9GAyyj0hVK97kPw5ZxMFs3jQiEQ6LLvUsBLdkA80" //The base64 encoded string output from Java; 
var iv = "dc0da04af8fee58593442bf834b30739" 
var salt = "dc0da04af8fee58593442bf834b30739" 

var aesUtil = new AesUtil(keySize, iterationCount); 
var plaintext = aesUtil.decrypt(salt, iv, encryptionKey, dataToDecrypt); 
console.log(plaintext); 

**//AESUtil - Utility class for CryptoJS** 
var AesUtil = function(keySize, iterationCount) { 
this.keySize = keySize/32; 
this.iterationCount = iterationCount; 
}; 

AesUtil.prototype.generateKey = function(salt, passPhrase) { 
    var key = CryptoJS.PBKDF2(passPhrase, CryptoJS.enc.Hex.parse(salt), 
    { keySize: this.keySize, iterations: this.iterationCount }); 
    return key; 
} 

AesUtil.prototype.decrypt = function(salt, iv, passPhrase, cipherText) { 
    var key = this.generateKey(salt, passPhrase); 
    var cipherParams = CryptoJS.lib.CipherParams.create({ 
    ciphertext: CryptoJS.enc.Base64.parse(cipherText) 
    }); 
    var decrypted = CryptoJS.AES.decrypt(cipherParams,key, 
    { iv: CryptoJS.enc.Hex.parse(iv) }); 
    return decrypted.toString(CryptoJS.enc.Utf8); 
} 
} 
相关问题