python代码:代码地址:
import logging
import io
from hashlib import sha1
from struct import pack, unpack
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())
@staticmethod
def decrypt(key, ibuf):
r"""
Return decrypted data.
"""
obuf = io.BytesIO()
totalSize = unpack("<I", ibuf.read(4))[0]
logger.debug("totalSize: {}".format(totalSize))
ibuf.seek(8)
aes = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
decryptor = aes.decryptor()
x = ibuf.read()
dec = decryptor.update(x) + decryptor.finalize()
obuf.write(dec[:totalSize])
return obuf.getvalue() # return obuf.getbuffer()
node.js代码:
function decrypt (key, ibuf) {
console.log(`totalSize: ${key.byteLength}`);
const obuf = Buffer.alloc(0);
const totalSize = ibuf.readUInt32LE(0);
console.log(`totalSize: ${totalSize}`);
const aesKey = crypto.createDecipheriv('aes-128-ecb', key, Buffer.alloc(0), { authTagLength: 0 });
//const aesKey = crypto.createCipheriv('aes-128-ecb', key, Buffer.alloc(0), { authTagLength: 0 });
const x = ibuf.slice(8);
// const x = ibuf.slice(4, totalSize + 16 - (totalSize % 16));
// aesKey.final() 这里报错, 解密的时候
// 报Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
const dec = Buffer.concat([aesKey.update(x), aesKey.final()]);
const resultBuf = dec.slice(0, totalSize);
return resultBuf;
}
go 代码:代码地址:
// standardDecrypt decrypt the CFB file format with ECMA-376 standard encryption.
func standardDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opts *Options) ([]byte, error) {
encryptionHeaderSize := binary.LittleEndian.Uint32(encryptionInfoBuf[8:12])
block := encryptionInfoBuf[12 : 12+encryptionHeaderSize]
header := StandardEncryptionHeader{
Flags: binary.LittleEndian.Uint32(block[:4]),
SizeExtra: binary.LittleEndian.Uint32(block[4:8]),
AlgID: binary.LittleEndian.Uint32(block[8:12]),
AlgIDHash: binary.LittleEndian.Uint32(block[12:16]),
KeySize: binary.LittleEndian.Uint32(block[16:20]),
ProviderType: binary.LittleEndian.Uint32(block[20:24]),
Reserved1: binary.LittleEndian.Uint32(block[24:28]),
Reserved2: binary.LittleEndian.Uint32(block[28:32]),
CspName: string(block[32:]),
}
block = encryptionInfoBuf[12+encryptionHeaderSize:]
algIDMap := map[uint32]string{
0x0000660E: "AES-128",
0x0000660F: "AES-192",
0x00006610: "AES-256",
}
algorithm := "AES"
_, ok := algIDMap[header.AlgID]
if !ok {
algorithm = "RC4"
}
verifier := standardEncryptionVerifier(algorithm, block)
secretKey, err := standardConvertPasswdToKey(header, verifier, opts)
if err != nil {
return nil, err
}
// decrypted data
x := encryptedPackageBuf[8:]
blob, err := aes.NewCipher(secretKey)
if err != nil {
return nil, err
}
decrypted := make([]byte, len(x))
size := 16
for bs, be := 0, size; bs < len(x); bs, be = bs+size, be+size {
blob.Decrypt(decrypted[bs:be], x[bs:be])
}
return decrypted, err
}
请大佬指教为什么我参考python代码写的node.js代码最后输出的内容是不一样的,py版和go版的可以解密成功,node.js的代码可以运行,但是最后解密出来的是不对的?是因为aes-128-ecb算法需要分块解密吗?
key 是16个字节的Buffer 类似这个 <Buffer 0b 9d 2f ab a2 d8 e6 e7 ac 2e c2 c5 a1 fc c4 a1> ibuf 是加密的密文,也是一个Buffer
解密?为什么是用的
createChipheriv
而不是createDechipheriv
你看有没有可能是这个地方:
这里只取了 8 个字节出来,但总长按理说是
totalSize
个字节。所以如果解密内容不足,可能解密是会出错的。我写了个小示例
加密解密没有问题。解密的部分试了,后两
Buffer.alloc(0)
和null
不影响,最后一个参数也没影响。所以如果你那里解密不出来,应该还是处理识别和处理上有问题。