Javascript 带计数器的CryptoJS解密

Javascript 带计数器的CryptoJS解密,javascript,aes,cryptojs,Javascript,Aes,Cryptojs,我有以下用于AES解密的python代码,我已经验证并正在使用 key=“密码” key=hashlib.sha256(key.encode(“utf-8”)).digest() iv=b‘这是一个IV456’#Random.new().read(AES.block_大小) iv_int=int(binascii.hexlify(iv),16)#将iv转换为Python整数。 ctr=Counter.new(AES.block_size*8,initial_value=iv_int)#创建一个i

我有以下用于AES解密的python代码,我已经验证并正在使用

key=“密码”
key=hashlib.sha256(key.encode(“utf-8”)).digest()
iv=b‘这是一个IV456’#Random.new().read(AES.block_大小)
iv_int=int(binascii.hexlify(iv),16)#将iv转换为Python整数。
ctr=Counter.new(AES.block_size*8,initial_value=iv_int)#创建一个iv=iv_int的新计数器对象。
aes=aes.new(键,aes.MODE\u CTR,计数器=CTR)
decryptData=aes.decrypt(encryptedData)#解密并返回明文。
现在我需要在python中使用转换此代码,我已经做了一些编码,但不知道计数器
ctr
是如何生成的

var i8a=新的Uint8Array(数据);
var password=“password”;
var key=CryptoJS.SHA256(密码);
var input=CryptoJS.lib.WordArray.create(i8a);
var output=CryptoJS.AES.decrypt(输入,密钥,{mode:CryptoJS.mode.CTR});
var str=output.toString(CryptoJS.enc.Base64);
但是
str
总是没有

编辑:

根据下面的评论,我添加了带有config的
iv
和noPadding选项,但解密返回为空

  var iv = "112197289293498629157884805399637669174";
  //iv = CryptoJS.enc.Base64.parse(iv); //enable this doesn't make any changes. 
  var output =CryptoJS.AES.decrypt(input, key,{ mode: CryptoJS.mode.CTR,iv:iv,padding: CryptoJS.pad.NoPadding});
在这里,我从python端获得了iv值
iv_int

并且无法从python脚本中删除
计数器
,在该脚本中会出现如下错误:,
“计数器”关键字参数是CTR模式所必需的

注意:我正在通过webRTC数据通道将加密数据从python发送到js

Edit2:

我在python中实际使用的python加密代码

  def encrypt(row):
        key = "password"
        key = hashlib.sha256(key.encode("utf-8")).digest()
        iv = b'This is an IV456' #Random.new().read(AES.block_size)
        iv_int = int(binascii.hexlify(iv), 16) 

        ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)
        cipher = AES.new(self.key, AES.MODE_CTR,counter=ctr)
        return base64.b64encode(cipher.encrypt(raw))
输入数据进行加密

fp = open(filepathFull, "rb")
while (True) and not done_reading:
    data = fp.read(16384)
    encrypted = encrypt(data) 
    sendWebrtcDataChannel(encrypted)

代码中需要进行以下更改:

  • 计数器的初始值必须用作IV。由于IV由ASCII字符组成,因此可以使用拉丁1编码器或十六进制编码器将其解析为十六进制字符串。IV必须通过
    解密
    传递
  • decrypt
    要求密文为
    CipherParams
    对象
  • CryptoJS默认使用CBC和PKCS7。其他值必须在
    decrypt
    中明确指定。由于CTR模式不使用填充,因此必须指定模式和填充
以下JavaScript代码与Python代码相同:

//Testdata:密文作为数组
变量数据=[0xa6、0x8a、0x3c、0x0d、0xeb、0x9a、0xfc、0x9d、0xb1、0x83、0xb0、0x47、0x9c、0x63、0x65、0x1d、0x16、0x6e、0x53、0xac、0xf4、0xda、0x0f、0xac、0xe3、0x56、0xf4、0xfe、0x2e、0xf5、0x1a、0x19、0xd5、0x50、0x5f、0x1a、0x85、0x34、0x6c、0xac、0x47、0xd6、0x2c];
var i8a=新的Uint8Array(数据);
var password=“password”;
var key=CryptoJS.SHA256(密码);
var iv=CryptoJS.enc.Latin1.parse(“这是一个IV456”);//使用Latin1编码器解析IV
//var iv=CryptoJS.enc.Hex.parse('5468697320697320616e204956343536');//或使用十六进制编码器
var input=CryptoJS.lib.WordArray.create(i8a);
var输出=CryptoJS.AES.decrypt(
{
ciphertext:input//将密文作为CipherParams对象传递
}, 
钥匙
{
iv:iv,//通过iv
mode:CryptoJS.mode.CTR,//指定模式
填充:CryptoJS.pad.NoPadding//指定填充
});
var str=output.toString(CryptoJS.enc.Base64);
console.log(str);
var str=output.toString(CryptoJS.enc.Utf8);
console.log(str)

不应该命名变量字符串,因为变量字符串是字符串的对象包装器。这可能会破坏你的很多代码。它可能不会破坏您发布的代码,但这可能取决于您正在执行的其他操作。这是偶然发生的,我会更正它。您的JavaScript代码没有指定IV。我希望您需要使用
IV_int
整数值(不管是什么——我不太了解Python加密库)作为
iv:…
选项和
模式:…
选项。crypto.js中没有相应的
计数器
类型,但指定IV和
CTR
模式应足以让crypto.js进行必要的计数。(但我想我对crypto.js也不是很在行!)Python
计数器
类型也知道以位为单位的块大小,但我假设密码知道它自己的块大小,所以这应该不是必需的。在这两种代码中,密码因键入错误而不同。正如@apsillers已经指出的,计数器的初始值必须用作IV(并传递给
decrypt
)。由于IV由ASCII字符组成,因此可以对其进行解析,例如使用拉丁1编码器。密文必须作为
CipherParams
对象传递给
decrypt
。此外,必须在
decrypt
调用中禁用填充。然后两个代码返回相同密码的相同明文(如果使用相同的密码)。我修复了密码的键入错误,添加了iv和no padding选项,解密后仍然得到空值。请查看编辑。感谢您的回答,我能够解密数据,但解密后的数据与发送数据不同。从python
encrypt(b'testData')
解密后通过webrtc数据通道发送js,我得到
var str1=output.toString(CryptoJS.enc.Base64)与内容
TsqtU5sHkNf/TIME
。发布的Python
解密方法(JavaScript代码为其定制)在该场景中扮演什么角色?解密与Python
decr一起工作吗