crypto.createCipheriv中的密钥长度无效

use*_*010 4 javascript cryptography node.js

我在NodeJS v8.11.0中使用以下代码生成了base64编码的密钥:

const secret = 'shezhuansauce';
const key = crypto.createHash('sha256').update(String(secret)).digest('base64');
//output is REtgV24bDB7xQYoMuypiBASMEaJbc59nJWChoXbbmsA=
Run Code Online (Sandbox Code Playgroud)

使用密钥,我尝试加密一个字符串:

var tobeEncrypted = 'some secret string';
const iv = crypto.randomBytes(16).toString('hex').slice(0, 16);
const cipher = crypto.createCipheriv('aes-256-ctr', key, iv);
const encrypted = cipher.update(String(tobeEncrypted), 'utf8', 'hex') + cipher.final('hex');
console.log(encrypted);
Run Code Online (Sandbox Code Playgroud)

但是,我收到一个错误:

crypto.js:219
this._handle.initiv(cipher, toBuf(key), toBuf(iv));
           ^
Error: Invalid key length
Run Code Online (Sandbox Code Playgroud)

密钥必须是base64字符串,因为我会将其存储在Cloud服务中,并且它仅接收base64字符串。

任何帮助表示赞赏。

tur*_*1ng 8

您需要的密钥长度为32字节(256位)。因此,如果将关键行更改为:

let key = crypto.createHash('sha256').update(String(secret)).digest('base64').substr(0, 32);
Run Code Online (Sandbox Code Playgroud)

它会工作。


Leo*_*Leo 5

另一种可能比将 64 位字符串切成前 32 个字节更好的替代方法是在digest() 调用之前简单地返回键的值:

let key = crypto.createHash('sha256').update(String(secret))
Run Code Online (Sandbox Code Playgroud)

如果密钥在转换为 Base 64 后被切割为 32 字节,则该切割后的字符串是无效的 Base64 字符串。


小智 5

您说您在 BASE 64 中存储了一个密钥,并且该密钥是 256 位(或 32 个字节)(我们看到您计算了 sha256),因此只需获取该 base64 密钥,然后您就可以轻松地获取字节,如下所示:

const key_in_bytes = Buffer.from(BASE_64_KEY, 'base64')
Run Code Online (Sandbox Code Playgroud)

您可以使用此密钥(以字节为单位)作为您的密钥:

const cipher = crypto.createCipheriv('aes-256-ctr', key_in_bytes, iv);
Run Code Online (Sandbox Code Playgroud)