我正在尝试加密用户输入,该用户输入首先由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脚本没有泄漏;如果数据库泄漏(因此iv
和encrypted output
)公开泄漏,最糟糕的情况是什么?
我一直在寻找其他似乎使用过时模块的问题,例如:
mcrypt:Decrypting strings in Python that were encrypted with MCRYPT_RIJNDAEL_256 in PHP
他们帮助我理解了问题,但显然还不够。