当前位置: 首页 > 知识库问答 >
问题:

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

王磊
2023-06-07

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解密有问题导致的,还是哪里有问题?

共有1个答案

姬烨磊
2023-06-07
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);
}
 类似资料:
  • python 代码:地址: node.js 代码: python 输入输出: node.js 输入输出: 请大佬指教为什么我参考 python 代码写的 node.js 代码最后输出的内容是不一样的?

  • python代码:代码地址: node.js代码: go 代码:代码地址: 请大佬指教为什么我参考python代码写的node.js代码最后输出的内容是不一样的,py版和go版的可以解密成功,node.js的代码可以运行,但是最后解密出来的是不对的?是因为aes-128-ecb算法需要分块解密吗?

  • 小白菜疑问,能不能详细地跟我说一下两种写法的区别? 题目:使用函数求素数和: 定义prime(p), 其中函数prime当用户传入参数p为素数时返回True,否则返回False 定义PrimeSum(m,n),函数PrimeSum返回区间[m, n]内所有素数的和。题目保证用户传入的参数1<=m<n 假设输入m=1,n=10 疑问:下面是两种不同的写法,第一个是我写的,第二个是正确答案TT,我不太

  • 下面的代码基于@a.bertucci提供的一个示例,这里使用Android上的RxJava以固定的间隔在UI中绘制对象,其中我使用计时器压缩了一个可观察对象。当我通过调用processDelayedItems()触发订阅时,压缩的Observable中的代码[A]只执行一次,一个项目被发送到[B]。我原本希望代码[A]在触发后继续运行,并保持每1500毫秒发出一次项,但显然它在这里只运行一次。 >

  • 问题内容: 我发布此消息是因为该主题刚刚在另一个问题/答案中提出,并且该行为没有得到很好的记录。 考虑数据框 我想获取由column定义的每个组的第一行和最后一行。 我试过了 但是,这并没有给我我所期望的。 如何获得每个组中的实际第一个和最后一个值? 问题答案: 一种选择是使用该方法: 但是,我还没有找到一种将它们整齐地聚合的方法。当然,总是可以使用构造函数: 注意:我明确使用了该属性,否则您必须

  • 比如给680,区间是676-680, 给681,区间是681-685, 给682,区间是681-685 给687,区间是686-680