2016-05-12 155 views
3

第1步:pbkdf2

var key = crypto.pbkdf2Sync('prancypoodle', 'sherylcrowe', 10000, 32, 'sha512'); 

創建的密碼,prancy poodle,鹽,它sherylcrowe一鍵創建鍵,重複10000次,出把一個32字節長的密鑰( AES-256-CBC需要這個長度)。AES-256-CBC壞解密

第2步:加密的東西

var cipher = crypto.createCipheriv('aes-256-cbc', key, 'dogsarefun'.toString("binary")); 

var crypted = cipher.update('wherearemysocks?'); 
crypted = Buffer.concat([crypted, cipher.final()]); 

第3步:解密&失敗

var decipher = crypto.createDecipheriv('aes-256-cbc', key, 'dogsarefun'.toString('binary')); 

var decrypted = decipher.update(crypted); 
decrypted = Buffer.concat([decrypted, decipher.final()]); 
Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt 
    at Error (native) 
    at Decipher.Cipher.final (crypto.js:150:26) 
    at repl:1:48 
    at REPLServer.defaultEval (repl.js:272:27) 
    at bound (domain.js:280:14) 
    at REPLServer.runBound [as eval] (domain.js:293:12) 
    at REPLServer.<anonymous> (repl.js:441:10) 
    at emitOne (events.js:101:20) 
    at REPLServer.emit (events.js:188:7) 
    at REPLServer.Interface._onLine (readline.js:219:10) 

我在做什麼錯?這看起來很正確,但卻是錯誤的。

回答

4

您需要爲CBC模式提供IV,並且它需要是塊大小(AES爲16字節)。 'dogsarefun'只有10個字節,所以其餘的字節未指定,可能(可能是)垃圾。

由於PKCS填充是默認的,CBC模式中使用了不正確的IV會導致不正確的填充上解密可能出現錯誤:套路:EVP_DecryptFinal_ex:壞解密

P.S.注意:這是貓被貓叮的互聯網。

+0

是否有什麼長度的密鑰一個很好的借鑑和IVS不同的算法需要什麼? – Breedly

+1

好點,[Wikipedia](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)提供了密鑰大小和塊大小,但沒有提及IV大小與塊大小相同,假設得很多。有幾本很好的書,如[*應用密碼學手冊*](http://cacr.uwaterloo.ca/hac/index.html)參見免費下載 *應用密碼學* Bruce Schneier *實用密碼術* Niels Ferguson和Bruce Schneier *加密解密*由HX Mel和Doris M. Baker(我真的很喜歡開局很好)。 – zaph

0

您需要使用createDecipheriv函數進行解密,並且您的IV必須是16個字符。

例子:

var crypto = require('crypto'); 
var buffer = require('buffer'); 

var key = crypto.pbkdf2Sync('prancypoodle', 'sherylcrowe', 10000, 32, 'sha512'); 

// Initialization vector must be 16 characters. 
var cipher = crypto.createCipheriv('aes-256-cbc', key, 
    new Buffer('1234567812345678', 'binary')); 

var crypted = cipher.update('wherearemysocks?'); 
console.log('Encrypted: %s', crypted); 
crypted = Buffer.concat([crypted, cipher.final()]); 
// Again, IV must be 16 characters. 
var decipher = crypto.createDecipheriv('aes-256-cbc', key, 
    new Buffer('1234567812345678', 'binary')); 

var decrypted = decipher.update(crypted); 
console.log('Decrypted: %s', decrypted); 

輸出:

Encrypted: #�j���(���� 
Decrypted: wherearemysocks? 
+0

由於許多(大多數)字節不是可打印字符,因此以十六進制顯示加密數據真的會更好。諸如「# j ( 」)之類的東西是毫無意義的,因爲丟失了很多字節。 – zaph

+1

嗯,我主要是爲了證明它曾經被掩蓋過(因爲它被加密了!),現在不是。:P – Switch