2014-02-09 76 views
4

我已經得到了下面的Java代碼,我想端口的Node.js:移植AES解密的Java代碼,Node.js加載

// Java 

byte[] rawKey = "deadbeefdeadbeef".getBytes("us-ascii"); 
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES"); 
Cipher cip = Cipher.getInstance("AES/ECB/NoPadding"); 
cip.init(Cipher.DECRYPT_MODE, skeySpec); 
byte[] plaintext = cip.doFinal(ciphertext, 0, ciphertext.length); 

這是我嘗試用Node.js的,使用流

// JS, using the crypto streams API 

var decipher = crypto.createDecipher('aes-128-ecb', 'deadbeefdeadbeef'); 
decipher.setAutoPadding(false); 
decipher.pipe(concat(function(plaintext) { console.log(plaintext); }); 
decipher.end(ciphertext); 

而且,還使用Node.js的嘗試老.update().final() API:

// JS, using the `.update()` and `.final()` API 

var decipher = crypto.createDecipher('aes-128-ecb', 'deadbeefdeadbeef'); 
decipher.setAutoPadding(false); 
var pieces = []; 
pieces.push(new Buffer(decipher.update(ciphertext))); 
pieces.push(new Buffer(decipher.final())); 
var plaintext = Buffer.concat(pieces); 

這兩版本產生正確長度(與輸入長度相同)的相同輸出,但是該輸出與在相同輸入緩衝器上運行的解密Java版本產生的明文不同。如何設置像上面配置的Java解碼器一樣的Node.js解碼?

謝謝。

+0

當您在JS代碼中指定AES-256時,您似乎在Java代碼中使用AES-128。我不確定JS API如何接受256位密碼的128位密鑰;也許它正在執行某種密鑰派生? – ntoskrnl

+0

我的不好,那是從舊代碼複製/粘貼!謝謝你指出。在發佈這個問題的時候,我已經計算出了很多。自那之後我就解決了這個問題,並且很快就會發佈一個答案。雖然,我並不熟悉加密技術,也不瞭解答案的含義:使用'crypto.createDecipheriv('aes-128-ecb','deadbeefdeadbeef','');'做了訣竅。 –

+0

@ntoskrnl:是的,有一段時間我用128位密鑰使用'aes-256-ecb',否則它不會拋出或指示錯誤。只是產生不需要的解密輸出。 –

回答

4

createDecipher實際上不像在Java中那樣使用密鑰。它使用一個密碼,它被輸入到一個基於密碼的密鑰推導函數(PBKDF)中,推導出的密鑰。因此,使用不同的密鑰並且沒有檢查密鑰正確性的方法,您將獲得隨機的純文本。

Node.js API沒有很好的命名,函數createDeciphercreateDecipheriv表明後者與前者相同,只是增加了IV。相反,createDecipher增加了一個完整的密鑰派生函數。

+0

@dimadima如果你不介意的話,爲你解答它,因爲我知道爲什麼這會產生如此巨大的差異,請指出你是否對代碼做了其他更改以使其工作 –

+0

非常感謝是的,改用IV函數是必須的。具體來說:'crypto.createDecipher('aes-128-ecb','deadbeefdeadbeef')' - >'crypto.createDecipheriv('aes-128-ecb' ,'deadbeefdeadbeef','')' –

+0

隨着v0.10.35節點總是拋出錯誤「node-crypto:Invalid IV length」if if use the proposed solution - any workaround? – Skomski