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