鍍金池/ 問(wèn)答/HTML/ Node加密解密編碼問(wèn)題

Node加密解密編碼問(wèn)題

編寫(xiě)了一個(gè)node的加密解密demo,遇到編碼問(wèn)題,關(guān)于加密與解密分別使用的是createCipherivcreateDecipheriv方法

node版本

$ node -v
v8.11.3

代碼編輯使用的Sublime Text 3 編碼為 UTF-8
終端編碼格式為 UTF-8

相關(guān)代碼

let crypto = require('crypto');

let algorithm = 'aes-128-cbc';
let key = '9cd5b4cf89949207';
let iv = 'e6db271db12d4d47';
let data = 'hello world';
// 輸入編碼
let inputEncoding = 'utf8';
// 輸出編碼
let outputEncoding = 'hex';

let cipher = (algorithm, key, iv, data, callback) => {
    let cip = crypto.createCipheriv(algorithm, key, iv);
    let ciphertext = cip.update(data, inputEncoding, outputEncoding) + cip.final(outputEncoding);
    callback(ciphertext);
};
let decipher = (algorithm, key, iv, ciphertext, callback) => {
    let decip = crypto.createDecipheriv(algorithm, key, iv);
    let data = decip.update(ciphertext,outputEncoding,inputEncoding) + decip.final(inputEncoding);
    callback(data);
};
cipher(algorithm, key, iv, data, (ciphertext) => {
    console.log(ciphertext);
    decipher(algorithm, key, iv, ciphertext, (data) => {
        console.log(data);
    })
})

你期待的結(jié)果是什么?實(shí)際看到的錯(cuò)誤信息又是什么?

1,設(shè)置輸入編碼與輸出編碼都為UTF-8時(shí),終端運(yùn)行出錯(cuò)

let inputEncoding = 'utf8';
let outputEncoding = 'utf8';

輸出結(jié)果如下

$ node temp.js
49??cY~?B?iU/
crypto.js:183
  var ret = this._handle.final();
                         ^

Error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
    at Decipheriv.final (crypto.js:183:26)
    at decipher (/Users/lkp/Desktop/NodeS/temp.js:19:78)
    at cipher (/Users/lkp/Desktop/NodeS/temp.js:24:5)
    at cipher (/Users/lkp/Desktop/NodeS/temp.js:15:5)
    at Object.<anonymous> (/Users/lkp/Desktop/NodeS/temp.js:22:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)

2 設(shè)置輸入編碼為utf8,輸出編碼為base64

let inputEncoding = 'utf8';
let outputEncoding = 'base64';

結(jié)果如下

ND0IOZDkqGNZfrxCnmlVLw==
hello world

3,設(shè)置輸入編碼為utf8,輸出編碼為hex

let inputEncoding = 'utf8';
let outputEncoding = 'hex';

結(jié)果如下

343d083990e4a863597ebc429e69552f
hello world

兩個(gè)問(wèn)題

1,aes-128-cbc 這樣的加密算法對(duì)應(yīng)的 key 以及 iv 的長(zhǎng)度是怎么確定的,key 與 iv分別在加密中起到了什么作用?
2,輸出編碼為utf8時(shí),為什么輸出的是 49??cY~?B?iU/ 這樣的亂碼?

回答
編輯回答
離殤

AES-128-CBC顧名思義,就是128位密鑰的AES分組密碼,CBC是指加密時(shí)使用的加密模式是密碼分組鏈模式。

AES的加密流程這個(gè)百度上都有,懶得抄了,IV是initial Value,用于首次加密前初始化分組的,16個(gè)字節(jié),128位。

UTF8是一個(gè)字符編碼,AES加密完的東西是一串不可預(yù)測(cè)的二進(jìn)制碼,你強(qiáng)行套一個(gè)字符編碼的話當(dāng)然編碼出來(lái)的都是亂碼,Base64不是字符編碼,是一種二進(jìn)制位轉(zhuǎn)換成可打印字符的編碼方式,所以你覺(jué)得很正常,因?yàn)樗緛?lái)就只有那64個(gè)字符可以打印,Hex16就是16個(gè)字符可以打印,都沒(méi)有亂碼,所以沒(méi)毛病

2018年6月16日 12:47