【问题标题】:Invalid key length in crypto.createCipherivcrypto.createCipheriv 中的密钥长度无效
【发布时间】:2018-06-21 07:50:26
【问题描述】:

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

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

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

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);

但是,我收到一个错误:

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

密钥必须是base64字符串,因为我将它存储在云服务中,它只接收base64字符串。

感谢任何帮助。

【问题讨论】:

  • 我如何在你的过程中解密?

标签: javascript node.js cryptography


【解决方案1】:

补充一句:密钥长度取决于算法,比如aes192是24字节,aes256是32字节。 您需要有一个 32 字节(256 位)的密钥长度。 因此,如果您将关键行更改为:

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

它会起作用的。

【讨论】:

    【解决方案2】:

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

    const key_in_bytes = Buffer.from(BASE_64_KEY, 'base64')
    

    你可以使用这个以字节为单位的密钥作为你的密钥:

    const cipher = crypto.createCipheriv('aes-256-ctr', key_in_bytes, iv);
    

    【讨论】:

    • 只有答案不会无缘无故截断秘密的哈希,并且可以扩展到其他编码方案,例如hex、utf8、latin1、ascii,不仅仅是base64。从技术上讲,base64 的编码可以通过使用.digest() 跳过,这将直接给出Buffer。
    • 虽然接受的答案是有效的,但由于上述原因,我更喜欢这种方法
    【解决方案3】:

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

    let key = crypto.createHash('sha256').update(String(secret))
    

    如果密钥在转换成base 64后被切割成32字节,那么被切割的字符串就是一个无效的base64字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      • 2021-06-17
      • 2010-12-18
      • 1970-01-01
      • 2015-04-03
      • 2018-07-03
      相关资源
      最近更新 更多