2017-08-02 92 views
1

我有java代碼,它爲我產生aes加密代碼,現在我正嘗試在javascript上使用crypto-js,但兩種代碼都提供了不同的密鑰,我不知道爲什麼以及如何在這裏得到同樣關鍵的是我的代碼java加密aes值和javascript加密值不匹配

public static String encrypt(String text, byte[] iv, byte[] key)throws Exception{ 

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); 
    System.out.println("KEY SPECCCC: "+keySpec); 
    IvParameterSpec ivSpec = new IvParameterSpec(iv); 
    cipher.init(Cipher.ENCRYPT_MODE,keySpec,ivSpec); 
    byte [] results = cipher.doFinal(text.getBytes("UTF-8")); 
    BASE64Encoder encoder = new BASE64Encoder(); 
    return encoder.encode(results); 
} 

JavaScript代碼

require(["crypto-js/core", "crypto-js/aes"], function (CryptoJS, AES) { 
     ciphertext = CryptoJS.AES.encrypt(JSON.stringify(jsondata), 
         arr.toString(),arr.toString()); 
    }); 

字符串爲UTF-8

var utf8 = unescape(encodeURIComponent(key)); 
var arr = []; 
for (var i = 0; i < utf8.length; i++) { 
    arr.push(utf8.charCodeAt(i)); 
} 
+0

如果您只使用對稱加密,你需要在服務器和客戶端完全相同的關鍵。如果您將加密密鑰從服務器發送到客戶端或其他方式需要加密對稱加密密鑰。最簡單的方法是使用TLS。如果你使用TLS,那麼數據和密鑰都是加密的,所以你不需要自己加密。這不提供任何安全性,只是一點混淆。您應該閱讀:https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/ –

+0

您的代碼不完整。你能證明你如何解碼Java和JS中的密鑰和IV以及實際值? –

+1

IV必須是不可預知的(閱讀:隨機)。不要使用靜態IV或與密鑰相同的值,因爲這會使密碼具有確定性,因此不會在語義上安全。觀察密文的攻擊者可以確定何時之前發送了相同的消息前綴。 IV不是祕密的,所以你可以把它和密文一起發送。通常,它只是在密文前面加上,然後在解密之前切掉。 –

回答

1

首先,即使您的代碼難以正常工作,您也無法正確解密它,因爲在Java中創建AES密碼時,您使用的是CBC密碼,而您正在實現PKCS5Padding的填充算法。 所以你的java代碼做到以下幾點: 當它得到輸入時,它首先將它分成16位塊,然後如果你的輸入沒有分成16個整體,那麼提醒將被填充以用相同數量的提醒填充塊。你可以看到我的意思是以下圖片。

enter image description here

所以它會做與Java端填充密碼,但在JavaScript部分,您加密既不宣佈將使用什麼類型的模式AES,也不宣佈它該做的是什麼類型的填充。因此,您應該將這些值添加到您的代碼中。您可以搜索以下代碼部分。

     mode:CryptoJS.mode.CBC, 
         padding: CryptoJS.pad.Pkcs7 

關於不同的密鑰,因爲您要發送的字節[]到你的加密方法,然後用這個未知的字節[],而你正在創建Key.You didnt提到它正在發生,爲什麼你的加密方法在你的程序中使用,但你應該在兩個方法中創建「Byte []鍵」。例如,你可以參考下面的代碼作爲生成的例子,但它不是生成密鑰的安全方式,我只是將它添加爲告訴你我的意思是你應該以同樣的方式生成兩個鍵。

//DONT USE THIS IMPLEMENTATION SINCE IT IS NOT SAFE! 
    byte[] key = (username + password).getBytes("UTF-8"); 
+0

默認情況下,CryptoJS使用CBC模式和PKCS#7填充。問題在於「密鑰」可能是CryptoJS將其視爲密碼並從中導出密鑰的字符串。 –

0

Java代碼生成一個加密的字符串,併爲JavaScript生成相同的加密字符串,下面的代碼工程!

var IVstring = CryptoJS.lib.ByteArray(your IV bytearray).toString(CryptoJS.enc.Base64); 
var keystring = CryptoJS.lib.ByteArray(your KEY bytearray).toString(CryptoJS.enc.Base64); 
var text = 'texttobeencrypted'; 
var key = CryptoJS.enc.Base64.parse(keystring); 
var iv = CryptoJS.enc.Base64.parse(IVstring); 
var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv}); 
console.log(encrypted.toString()); 

腳本鏈接: 添加CryptJS,AES和 https://greasyfork.org/scripts/6696-cryptojs-lib-bytearray/code/CryptoJSlibByteArray.js