2014-03-24 150 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); 
} 
} 
相關問題