用PHP加密字符串(openssl);然后在python3中解密

时间:2019-10-22 12:04:13

标签: php python encryption openssl

我正在尝试加密用户输入,该用户输入首先由PHP进行了验证和清除。然后,数据使用openssl加密,并存储在MYSQL后端中。随着时间的流逝,我们希望下载该表并使用Python对其解密。因此,我正在考虑跨语言要求。

我将以下字符串作为用户输入:

someone.somebody@blabla.com

使用PHP的内置方法对此进行了消毒:

filter_var($verifiedMail, FILTER_SANITIZE_EMAIL)

然后我将其传递给PHP脚本的加密逻辑:

$lock = "82YoH8jE7TJyEX2hLzFe35wTPaaDgVP1";     // use a 256 bit key!!!!!
/*Ideally you'd define the $lock as defined constant and store it elsewhere!!!*/
$method = 'aes-256-cfb';

$ivlen = openssl_cipher_iv_length($method);
$isSecure = false;
do{
    $iv = openssl_random_pseudo_bytes($ivlen,$isSecure);
}while(!isSecure);

$mailStorage = openssl_encrypt($mail, $method, $lock, 0, $iv);

unset($method, $lock, $ivlen);

在SQL数据库中,我存储了两个变量:$iv$mailStorage 对于此迭代,这些值为:

$iv = '1abcd16944cc06c09e1d1635108a9077';
$mailStorage = 'gRDzkzHiysRqfjNXAYY+TWJ+88LtUcWfPFkn';

$iv变量插入数据库时​​,通过调用bin2hex($iv)将其存储为十六进制值。到目前为止,一切都很好; (我猜是吗?)

这些值在数据库中,并且PHP脚本可以正常运行而不会引发错误。因此,我继续研究Python解密部分。与此相关的块是:

import binascii
from Crypto.Cipher import AES
from base64 import b64decode

securedoutput = "gRDzkzHiysRqfjNXAYY+TWJ+88LtUcWfPFkn"  #the result of the encryption done by php
vector = "1abcd16944cc06c09e1d1635108a9077"# the IV generated by PHP and stored as hex in the database
password = "82YoH8jE7TJyEX2hLzFe35wTPaaDgVP1"##the key used for encryption

iv = binascii.unhexlify(vector)
password = password.encode()
cipher = AES.new(password, AES.MODE_CFB, iv)
securedoutput = b64decode(securedoutput)
data = cipher.decrypt(securedoutput)
print(data)
print(data.decode())

我首先将十六进制初始化向量转换回二进制。并且我对python模块似乎需要的密码进行了编码。

当我打印出data变量时,我得到:

b'sBD\xec@\x90\xbe\xe3\xe6\xccdv\x13\xb8\xb06@\x1a\xe6r\x82\xdfwe\xb0\xf4\x80'

当应用data.decode()时,我得到: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xec in position 3: invalid continuation byte

我的主要问题是:为什么现在的python输出与PHP输入匹配?加密和/或解密字符串时,我在做什么错?

另一个问题-与防御性编程原理更相关的与此PHP块有关:

$isSecure = false;
do{
    $iv = openssl_random_pseudo_bytes($ivlen,$isSecure);
}while(!isSecure);

我应该对此while循环添加一个限制吗?还是我可以假设openssl不会花100次迭代来找到$iv的安全值?我应该为此考虑些什么?

最后;密码学对我来说是一个全新的领域,过去几天我一直在阅读初始化向量,加密模式等内容。据我所知,这应该是安全的。还是我公然错了?我没有应用填充,因为我被认为CFB模式不需要填充。假设我的PHP脚本没有泄漏;如果数据库泄漏(因此ivencrypted output)公开泄漏,最糟糕的情况是什么?

我一直在寻找其他似乎使用过时模块的问题,例如:

mcrypt:Decrypting strings in Python that were encrypted with MCRYPT_RIJNDAEL_256 in PHP

他们帮助我理解了问题,但显然还不够。

0 个答案:

没有答案
相关问题