为什么这个rc4算法最后输出的值不一样,一个node.js写的,一个python写的?

py代码如下:

import functools, io, logging
from hashlib import md5
from struct import pack

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms

    def verifypw(password, salt, encryptedVerifier, encryptedVerifierHash):
        r"""
        Return True if the given password is valid.

            >>> password = 'password1'
            >>> salt = b'\xe8w,\x1d\x91\xc5j7\x96Ga\xb2\x80\x182\x17'
            >>> encryptedVerifier = b'\xc9\xe9\x97\xd4T\x97=1\x0b\xb1\xbap\x14&\x83~'
            >>> encryptedVerifierHash = b'\xb1\xde\x17\x8f\x07\xe9\x89\xc4M\xae^L\xf9j\xc4\x07'
            >>> DocumentRC4.verifypw(password, salt, encryptedVerifier, encryptedVerifierHash)
            True
        """
        # https://msdn.microsoft.com/en-us/library/dd952648(v=office.12).aspx
        block = 0
        key = _makekey(password, salt, block)
        cipher = Cipher(algorithms.ARC4(key), mode=None, backend=default_backend())
        decryptor = cipher.decryptor()
        verifier = decryptor.update(encryptedVerifier)
        verfiferHash = decryptor.update(encryptedVerifierHash)
        hash = md5(verifier).digest()
        logging.debug([verfiferHash, hash])
        return hash == verfiferHash

参考py写的node.js代码如下

makeKey 得到的key 是 20bf32ddf540858c513744af0f24e03c 16进制表示

function verifyPassword (password, salt, encryptedVerifier, encryptedVerifierHash) {
  const block = 0;
  const key = makeKey(password, salt, block);
// 要跑的话 ,这里直接换成 const key = Buffer.from('20bf32ddf540858c513744af0f24e03c', 'hex')
  console.log('verifyPassword-->key', key.toString('hex'));
  const cipher = crypto.createDecipheriv('rc4', key, '');
  // cipher.setAutoPadding(false);
  const verifier = Buffer.concat([cipher.update(encryptedVerifier), cipher.final()]);

  const hash = crypto.createHash('md5').update(verifier).digest();

  const cipher2 = crypto.createDecipheriv('rc4', key, '');
  // cipher2.setAutoPadding(false);

  const verifierHash = Buffer.concat([cipher2.update(encryptedVerifierHash), cipher2.final()]);

  console.log('xxx-->', [verifierHash, hash]);
// 这里输出 xxx--> [
  //<Buffer 4a 64 05 f3 99 92 ba d5 14 9a 2c d0 f3 7d 14 0c>,
  //<Buffer 38 f4 71 96 7a 53 bf f5 60 29 06 3c 21 12 1b 5c>
//]  这里不相同
  return verifierHash.equals(hash);
}

const password = 'password1';
const salt = Buffer.from('e8772c1d91c56a37964761b280183217', 'hex');
const encryptedVerifier = Buffer.from('c9e997d454973d310bb1ba701426837e', 'hex');
const encryptedVerifierHash = Buffer.from('b1de178f07e989c44dae5e4cf96ac407', 'hex');
const valid = verifyPassword(password, salt, encryptedVerifier, encryptedVerifierHash);
console.log('valid-->', valid);

node.js 的解密参数全是和py的一样,打印出来的key也是一样的,说明makeKey方法是一样的,

就是接下来的rc4解密,不知道是我node.js哪里写的不对,最后解密出来的verifierHash和 hash 不一样,求大神解答下,是不是node.js这里的rc4解密有问题导致的,还是哪里有问题?

阅读 2.1k
1 个回答
function verifyPassword (password, salt, encryptedVerifier, encryptedVerifierHash) {
  const block = 0;
  const key = makeKey(password, salt, block);
  console.log('verifyPassword-->key', key.toString('hex'));

  let cipher = crypto.createDecipheriv('rc4', key, '');
  const verifier = Buffer.concat([cipher.update(encryptedVerifier), cipher.final()]);
  const hash = crypto.createHash('md5').update(verifier).digest();

  cipher = crypto.createDecipheriv('rc4', key, '');
  const verifierHash = Buffer.concat([cipher.update(encryptedVerifierHash), cipher.final()]);

  console.log('xxx-->', [verifierHash, hash]);
  return verifierHash.equals(hash);
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏