Javascript的CryptoJS.enc.base64.stringify(data)在Python3/Django中的逆运算是什么?
What is inverse operation of Javascript's CryptoJS.enc.base64.stringify(data) in Python3/Django?
我正在尝试在 Javascript 中加密并在 Python/Django 中解密相同的数据。
免责声明:不是生产级代码,而是学习概念
我通过 Diffie Hellman(Ajax 使用 jQuery)生成一个密钥,我将其传递给下面的加密函数。输入一般是JSON格式的ID和密码。
这就是加密的方式。 {在某处找到代码。}
function toWordArray(str){
return CryptoJS.enc.Utf8.parse(str);
}
function toString(words){
return CryptoJS.enc.Utf8.stringify(words);
}
function toBase64String(words){
return CryptoJS.enc.Base64.stringify(words);
}
function encrypt(input, key){
console.log("Input: " + input);
var PROTOCOL_AES256 = 2;
var secret_key = CryptoJS.SHA256(key);
var header = toWordArray("AMAZON" + String.fromCharCode(PROTOCOL_AES256));
var iv = CryptoJS.lib.WordArray.random(16);
var body = CryptoJS.AES.encrypt(input, secret_key, {iv: iv});
// construct the packet
// HEADER + IV + BODY
header.concat(iv);
header.concat(body.ciphertext);
console.log("Bytes before Base64 encoding: " + header); //Line 1
// encode in base64
return toBase64String(header);
}
我得到的输出如下:
final key: 47 signin:119:33
Input: {"name":"Buzz","password":"lightyear"} signin:55:25
Bytes before Base64 encoding: 414d415a4f4e02e8ec9b8a949eb754e305acfbe5207f1ebe75272c18146bca57ce399928c0ffd7e506d90e11b011da42b1bd8d2393ec59cc926cef33c2121da3f48dfd59925138 signin:67:25
Payload: QU1BWk9OAujsm4qUnrdU4wWs++Ugfx6+dScsGBRrylfOOZkowP/X5QbZDhGwEdpCsb2NI5PsWcySbO8zwhIdo/SN/VmSUTg= signin:137:37
XHRGEThttp://127.0.0.1:8000/Shenzen/actsignin/?encrypted_string=QU1BWk9OAujsm4qUnrdU4wWs%2B%2BUgfx6%2BdScsGBRrylfOOZkowP%2FX5QbZDhGwEdpCsb2NI5PsWcySbO8zwhIdo%2FSN%2FVmSUTg%3D
[HTTP/1.1 500 Internal Server Error 24ms]
AES failed.
现在我在python中解码如下:
encrypted_string = request.GET['encrypted_string']
print("Encrypted string decoded: ",base64.b64decode(encrypted_string)) #Line 2
print("----")
sha256_key = SHA256.new(data=bytes(key))
cipher = AES.new(sha256_key.digest(),AES.MODE_CBC)
print(cipher.decrypt(base64.b64decode(encrypted_string)))
[12/Oct/2019 18:39:41] "GET /Shenzen/dh/?step=calcval&level1=37 HTTP/1.1" 200 16
Encrypted string decoded: b"AMAZON\x02\xcb0\xb5~ \xbf<\x96\x16\x0eJY@\x88\xfe\x94\xc28\xf2j\x19n\x8f\x8d\xdb\xb6yc\x89-L\x93\xa3\x9f\xc3i\xd5\xf4e4'|\xa1\x1f\x9d\xb9k\x95O\xb9<\xc3\xa0\xd7\xa6B^\x85+SSToe"
----
Internal Server Error: /Shenzen/actsignin/
Traceback (most recent call last):
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/hell/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/hell/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/hell/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/UrbanHell/Shenzen/views.py", line 67, in actsignin
print(cipher.decrypt(base64.b64decode(encrypted_string)))
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/hell/lib/python3.6/site-packages/Crypto/Cipher/_mode_cbc.py", line 246, in decrypt
raise ValueError("Data must be padded to %d byte boundary in CBC mode" % self.block_size)
ValueError: Data must be padded to 16 byte boundary in CBC mode
[12/Oct/2019 18:39:44] "GET /Shenzen/actsignin/?encrypted_string=QU1BWk9OAsswtX4gvzyWFg5KWUCI%2FpTCOPJqGW6Pjdu2eWOJLUyTo5%2FDadX0ZTQnfKEfnblrlU%2B5PMOg16ZCXoUrU1NUb2U%3D HTTP/1.1" 500 17651put
我希望第 1 行和第 2 行的输出相等,但这是我得到的:
Javascript Bytes before Base64 encoding: 414d415a4f4e02e8ec9b8a949eb754e305acfbe5207f1ebe75272c18146bca57ce399928c0ffd7e506d90e11b011da42b1bd8d2393ec59cc926cef33c2121da3f48dfd59925138 signin:67:25
Python Encrypted string decoded: b"AMAZON\x02\xcb0\xb5~ \xbf<\x96\x16\x0eJY@\x88\xfe\x94\xc28\xf2j\x19n\x8f\x8d\xdb\xb6yc\x89-L\x93\xa3\x9f\xc3i\xd5\xf4e4'|\xa1\x1f\x9d\xb9k\x95O\xb9<\xc3\xa0\xd7\xa6B^\x85+SSToe"
你能解释一下发生了什么吗?如何得到与javascript相同的字符串?或如何将 Python 中的字符串转换为可解密的(?)数据。
在JavaScript-code中,一个header(如hexstring:414d415a4f4e02
),随机生成的IV和密文拼接起来,进行Base64编码。在 Python-code 中,连接的数据是 Base64 解码的。然而,分裂成header、IV和密文似乎并没有执行。因此,解密时缺少密文和 IV。而不是密文,连接的数据用于解密,这是错误的。而AES-instance是在没有IV的情况下创建的,这也是错误的。
在 JavaScript-side 上,在 Base64 编码之前的串联数据 以十六进制表示形式给出:
414d415a4f4e02e8ec9b8a949eb754e305acfbe5207f1ebe75272c18146bca57ce399928c0ffd7e506d90e11b011da42b1bd8d2393ec59cc926cef33c2121da3f48dfd59925138
在 Python-side 上,在 Base64 解码后的串联数据 以十六进制表示形式给出:
414d415a4f4e02cb30b57e20bf3c96160e4a594088fe94c238f26a196e8f8ddbb67963892d4c93a39fc369d5f46534277ca11f9db96b954fb93cc3a0d7a6425e852b5353546f65
数据从 IV 开始明显不同(即从第 8 个字节开始)。 JavaScript-code 为每个 运行 生成一个随机 IV,因此每个 运行 的密文也不同。很有可能两个数据都来自不同的运行s,因为开头是一样的,偏差是从每个运行中随机产生的部分开始的].否则,必须以这种特有的方式在别处更改数据(并且可能不是通过发布的代码)。
可能还有一个padding-issue。 CryptoJS uses PKCS7-padding by default. In contrast, PyCrypto/PyCryptodome 默认不使用填充(即用户必须手动填充),因此 Python-side 上的填充可能不会在解密过程中自动删除。
我正在尝试在 Javascript 中加密并在 Python/Django 中解密相同的数据。
免责声明:不是生产级代码,而是学习概念
我通过 Diffie Hellman(Ajax 使用 jQuery)生成一个密钥,我将其传递给下面的加密函数。输入一般是JSON格式的ID和密码。
这就是加密的方式。 {在某处找到代码。}
function toWordArray(str){
return CryptoJS.enc.Utf8.parse(str);
}
function toString(words){
return CryptoJS.enc.Utf8.stringify(words);
}
function toBase64String(words){
return CryptoJS.enc.Base64.stringify(words);
}
function encrypt(input, key){
console.log("Input: " + input);
var PROTOCOL_AES256 = 2;
var secret_key = CryptoJS.SHA256(key);
var header = toWordArray("AMAZON" + String.fromCharCode(PROTOCOL_AES256));
var iv = CryptoJS.lib.WordArray.random(16);
var body = CryptoJS.AES.encrypt(input, secret_key, {iv: iv});
// construct the packet
// HEADER + IV + BODY
header.concat(iv);
header.concat(body.ciphertext);
console.log("Bytes before Base64 encoding: " + header); //Line 1
// encode in base64
return toBase64String(header);
}
我得到的输出如下:
final key: 47 signin:119:33
Input: {"name":"Buzz","password":"lightyear"} signin:55:25
Bytes before Base64 encoding: 414d415a4f4e02e8ec9b8a949eb754e305acfbe5207f1ebe75272c18146bca57ce399928c0ffd7e506d90e11b011da42b1bd8d2393ec59cc926cef33c2121da3f48dfd59925138 signin:67:25
Payload: QU1BWk9OAujsm4qUnrdU4wWs++Ugfx6+dScsGBRrylfOOZkowP/X5QbZDhGwEdpCsb2NI5PsWcySbO8zwhIdo/SN/VmSUTg= signin:137:37
XHRGEThttp://127.0.0.1:8000/Shenzen/actsignin/?encrypted_string=QU1BWk9OAujsm4qUnrdU4wWs%2B%2BUgfx6%2BdScsGBRrylfOOZkowP%2FX5QbZDhGwEdpCsb2NI5PsWcySbO8zwhIdo%2FSN%2FVmSUTg%3D
[HTTP/1.1 500 Internal Server Error 24ms]
AES failed.
现在我在python中解码如下:
encrypted_string = request.GET['encrypted_string']
print("Encrypted string decoded: ",base64.b64decode(encrypted_string)) #Line 2
print("----")
sha256_key = SHA256.new(data=bytes(key))
cipher = AES.new(sha256_key.digest(),AES.MODE_CBC)
print(cipher.decrypt(base64.b64decode(encrypted_string)))
[12/Oct/2019 18:39:41] "GET /Shenzen/dh/?step=calcval&level1=37 HTTP/1.1" 200 16
Encrypted string decoded: b"AMAZON\x02\xcb0\xb5~ \xbf<\x96\x16\x0eJY@\x88\xfe\x94\xc28\xf2j\x19n\x8f\x8d\xdb\xb6yc\x89-L\x93\xa3\x9f\xc3i\xd5\xf4e4'|\xa1\x1f\x9d\xb9k\x95O\xb9<\xc3\xa0\xd7\xa6B^\x85+SSToe"
----
Internal Server Error: /Shenzen/actsignin/
Traceback (most recent call last):
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/hell/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/hell/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/hell/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/UrbanHell/Shenzen/views.py", line 67, in actsignin
print(cipher.decrypt(base64.b64decode(encrypted_string)))
File "/home/tarunmaganti/Documents/AbhiramSlavery/ProjectLogin/hell/lib/python3.6/site-packages/Crypto/Cipher/_mode_cbc.py", line 246, in decrypt
raise ValueError("Data must be padded to %d byte boundary in CBC mode" % self.block_size)
ValueError: Data must be padded to 16 byte boundary in CBC mode
[12/Oct/2019 18:39:44] "GET /Shenzen/actsignin/?encrypted_string=QU1BWk9OAsswtX4gvzyWFg5KWUCI%2FpTCOPJqGW6Pjdu2eWOJLUyTo5%2FDadX0ZTQnfKEfnblrlU%2B5PMOg16ZCXoUrU1NUb2U%3D HTTP/1.1" 500 17651put
我希望第 1 行和第 2 行的输出相等,但这是我得到的:
Javascript Bytes before Base64 encoding: 414d415a4f4e02e8ec9b8a949eb754e305acfbe5207f1ebe75272c18146bca57ce399928c0ffd7e506d90e11b011da42b1bd8d2393ec59cc926cef33c2121da3f48dfd59925138 signin:67:25
Python Encrypted string decoded: b"AMAZON\x02\xcb0\xb5~ \xbf<\x96\x16\x0eJY@\x88\xfe\x94\xc28\xf2j\x19n\x8f\x8d\xdb\xb6yc\x89-L\x93\xa3\x9f\xc3i\xd5\xf4e4'|\xa1\x1f\x9d\xb9k\x95O\xb9<\xc3\xa0\xd7\xa6B^\x85+SSToe"
你能解释一下发生了什么吗?如何得到与javascript相同的字符串?或如何将 Python 中的字符串转换为可解密的(?)数据。
在JavaScript-code中,一个header(如hexstring:
414d415a4f4e02
),随机生成的IV和密文拼接起来,进行Base64编码。在 Python-code 中,连接的数据是 Base64 解码的。然而,分裂成header、IV和密文似乎并没有执行。因此,解密时缺少密文和 IV。而不是密文,连接的数据用于解密,这是错误的。而AES-instance是在没有IV的情况下创建的,这也是错误的。在 JavaScript-side 上,在 Base64 编码之前的串联数据 以十六进制表示形式给出:
414d415a4f4e02e8ec9b8a949eb754e305acfbe5207f1ebe75272c18146bca57ce399928c0ffd7e506d90e11b011da42b1bd8d2393ec59cc926cef33c2121da3f48dfd59925138
在 Python-side 上,在 Base64 解码后的串联数据 以十六进制表示形式给出:
414d415a4f4e02cb30b57e20bf3c96160e4a594088fe94c238f26a196e8f8ddbb67963892d4c93a39fc369d5f46534277ca11f9db96b954fb93cc3a0d7a6425e852b5353546f65
数据从 IV 开始明显不同(即从第 8 个字节开始)。 JavaScript-code 为每个 运行 生成一个随机 IV,因此每个 运行 的密文也不同。很有可能两个数据都来自不同的运行s,因为开头是一样的,偏差是从每个运行中随机产生的部分开始的].否则,必须以这种特有的方式在别处更改数据(并且可能不是通过发布的代码)。
可能还有一个padding-issue。 CryptoJS uses PKCS7-padding by default. In contrast, PyCrypto/PyCryptodome 默认不使用填充(即用户必须手动填充),因此 Python-side 上的填充可能不会在解密过程中自动删除。