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

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

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

你看有没有可能是这个地方:

    const x = ibuf.slice(8);

const dec = Buffer.concat([aesKey.update(x), aesKey.final()]);

这里只取了 8 个字节出来,但总长按理说是 totalSize 个字节。所以如果解密内容不足,可能解密是会出错的。


2023-05-24 补充

我写了个小示例

const algorithm = "aes-128-ecb";

function encrypt(key, content) {

const aes = crypto.createCipheriv(algorithm, key, null);

let result = Buffer.concat([

aes.update(content, "utf8"),

aes.final()

]);

return result;

}

function decrypt(key, data) {

const aesKey = crypto.createDecipheriv(algorithm, key, Buffer.alloc(0), { authTagLength: 0 });

const dec = Buffer.concat([aesKey.update(data), aesKey.final()]);

return dec;

}

const key = randomBytes(16);

console.log("key", key);

const data = encrypt(key, "hello world, hi world, .....");

console.log(data);

const literal = decrypt(key, data).toString("utf-8");

console.log(literal);

加密解密没有问题。解密的部分试了,后两 Buffer.alloc(0)null 不影响,最后一个参数也没影响。所以如果你那里解密不出来,应该还是处理识别和处理上有问题。

以上是 为什么这三个算法最后输出的值不一样,一个node.js写的,一个python和go写的? 的全部内容, 来源链接: utcz.com/p/938891.html

回到顶部