【问题标题】:Nodejs decrypt using crypto error wrong final block lengthNodejs使用加密错误解密最终块长度错误
【发布时间】:2014-05-31 10:34:47
【问题描述】:

我使用此代码加密/解密字符串值

var crypto = require('crypto');

function encrypt(text){
    var cipher = crypto.createCipher('aes-256-cbc','secret key');
    var encrypted = cipher.update(text.toString(),'utf8','hex') + cipher.final('hex');
    return encrypted;
}

function decrypt(text){
    var decipher = crypto.createDecipher('aes-256-cbc','secret key');
    var decrypted = decipher.update(text.toString(),'hex','utf8') + decipher.final('utf8');
    return decrypted ;
}

module.exports.encrypt = encrypt;
module.exports.decrypt = decrypt;

当我尝试解密未加密的东西时,例如解密('test')它会抛出以下错误:

crypto.js:292
  var ret = this._binding.final();
                          ^
TypeError: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
    at Decipher.Cipher.final (crypto.js:292:27)

我也尝试使用缓冲区但没有成功,但在 Internet 上找不到任何解决方案。

真正的问题是我用它来解密 cookie 值。如果黑客创建了一个值为“test”的虚假 cookie,它将使我的程序崩溃。

【问题讨论】:

标签: node.js encryption cryptography


【解决方案1】:

AES-CBC 的输出(没有密文窃取)始终是 16 个字节(32 个十六进制字符)的倍数。由于您根本不提供十六进制字符(“test”),并且由于字符串不是 32 个十六进制字符的倍数,因此您将始终看到错误。

所以这个:

000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F

例如是有效的。

因此,您需要检查您得到的内容是否包含正确的字符并且长度是否正确。为了确保您没有收到任何填充或内容相关的错误,您需要在最后放置一个通过密文计算的(十六进制编码的)HMAC 值。然后首先检查编码、长度,然后检查 HMAC。如果 HMAC 是正确的,则可以确保明文在解密后不会包含任何无效信息。

【讨论】:

  • ?真正的问题是我用它来解密 cookie 值。如果黑客创建了一个值为“test”的虚假 cookie,它将使我的程序崩溃。如何修改我的解密代码以使其接受任何字符串?
  • 测试字符串的长度,如果长度不合适就填充?如果长度不合适,或者直接拒绝它。但请注意,如果攻击者提交无效值,您不会因行为不同而无意中向攻击者提供信息。
  • @BobbyShark 啊,现在我明白了,您是在故意创建无效输入。没问题,修改答案。您不想修改代码以“接受任何字符串”。你想要的是它在开始解密之前以一种可以控制的方式快速失败。
  • @owlstead 好吧,我只想解密任何内容而不会出现该错误。我可以解密我的加密 cookie,但如果有人更改了 cookie 值,那么解密函数会抛出错误。只是说我对加密很不了解:) 所以我想我必须检查我的 cookie 值的长度,以及在发送解密之前它是否是十六进制值?
  • @BobbyShark,您发明了一种脆弱且不安全的登录机制。那里有许多发展良好且定义明确的策略,这些策略将超出您在这里提出的建议,您应该使用其中之一。例如,如何阻止攻击者收集多个“随机短语”,然后尝试其中几个直到匹配?
【解决方案2】:

我也遇到了同样的问题。我必须通过所有 cmets 来检查答案,@Alexey Ten 的评论帮助了我。因此,为了使@Alexey Ten 的答案在下面的变化更加明显。

var crypto = require('crypto');

function encrypt(text){
  try{
    var cipher = crypto.createCipher('aes-256-cbc','secret key');
    var encrypted = cipher.update(text.toString(),'utf8','hex') + cipher.final('hex');
    return encrypted;
    } catch(exception) {
      throw exception;
    }
}

function decrypt(text){
try{
    var decipher = crypto.createDecipher('aes-256-cbc','secret key');
    var decrypted = decipher.update(text.toString(),'hex','utf8') + decipher.final('utf8');
    return decrypted ;
  } catch(exception) {
     throw exception;
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 2014-02-13
    • 1970-01-01
    • 2020-11-03
    • 2014-05-02
    • 1970-01-01
    • 2017-12-20
    相关资源
    最近更新 更多