我有一个PHP页面,该页面遍历CSV文件并使用以下功能对“电子邮件”列进行加密:
function my_encrypt($data, $key)
{
// Remove the base64 encoding from our key
$encryption_key = base64_decode($key);
// Generate an initialization vector
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
// Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector.
$encrypted = openssl_encrypt($data, 'aes-256-cbc', $encryption_key, 0, $iv);
// The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)
return base64_encode($encrypted . '::' . $iv);
}
在应用的另一部分,我使用以下方法解密返回的值:
function my_decrypt($data, $key)
{
// Remove the base64 encoding from our key
$encryption_key = base64_decode($key);
// To decrypt, split the encrypted data from our IV - our unique separator used was "::"
list($encrypted_data, $iv) = explode('::', base64_decode($data), 2);
return openssl_decrypt($encrypted_data, 'aes-256-cbc', $encryption_key, 0, $iv);
}
在大多数情况下,这一切都可以顺利进行,但是不时地,解密后的值会返回其中包含一些奇怪的字符。
例如:返回了rsmi3�6CTΣ%mecompany.com
而不是rsmith@somecompany.com
。
我不确定输入或输出是否不好,但是我猜想这与上传的CSV文件有关……编码问题?这些字符是什么意思,它们是在什么条件下产生的?
这是我用来将加密值添加到CSV的代码:
$file = fopen(get_stylesheet_directory() . "/emma_members.csv", "r"); //Open the old file for reading
$newFile = fopen(get_stylesheet_directory() . "/emma_members_new.csv", "w"); //Create a new file for writing
if (!$file) error_log('ERROR opening file');
if (!$newFile) error_log('ERROR creating file');
$columns = ['email', 'member_id', 'member_since', 'plaintext_preferred', 'bounce_count', 'status_name', 'last_modified_at', 'city', 'first_name', 'last_name', 'request-demo', 'job-function', 'title', 'country', 'current-ams', 'opt-in', 'address-2', 'unique-identifier', 'state', 'postal_code', 'web-address', 'address', 'phone-number', 'company', 'area-of-specialization', 'work-phone'];
while (($data = fgetcsv($file)) !== FALSE) {
$row = array_combine($columns, $data);
$email = "{$row['email']}";
$uid = my_encrypt($email, ENCRYPT_KEY_1);
$row['unique-identifier'] = $uid;
$ret = fputcsv($newFile, array_values($row));
}
因此,在对数千封电子邮件进行了大量测试之后,my_encrypt
函数似乎返回了一些错误的值,具体取决于输入的内容。并非每个电子邮件地址都发生这种情况,但就我的用例而言,甚至1个也太多了。
我什至试图摆脱数据和iv之间的::
,但这也不起作用(尽管可能我做错了)。
无论如何,我最终在其位置使用了以下功能,一切都很好:
function encrypt_decrypt($action, $string) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = PHRASE_1;
$secret_iv = PHRASE_2;
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if ( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
} else if( $action == 'decrypt' ) {
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
答案 0 :(得分:0)
我测试了您的加密和解密功能,它们按预期工作,因此,这种现象的原因似乎是设备上的文件编码不同。
尤其是在读取CSV文件时,有时(windows)设备会更改编码,并且您会得到一些奇怪的字符,如显示的字符。我的建议是使用其他编码作为默认编码(ISO ...)读取文件。
我设置了一个实时示例,它“证明”了简单的字符串加密和解密的正确性:https://paiza.io/projects/e/Y-1gy9Y3b-VAlXAMG4odng
结果很简单:
plaintext: rsmith@somecompany.com
ciphertext: Y0RrMWRwR1pWeGtGbFdic3dIVmFzVmp4VUFYemJGdUhzMStRSll6akIwWT06Orf+twLGopVa4083RckEw44=
decryptedtext: rsmith@somecompany.com
代码如下:
<?php
function my_encrypt($data, $key)
{
// Remove the base64 encoding from our key
$encryption_key = base64_decode($key);
// Generate an initialization vector
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
// Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector.
$encrypted = openssl_encrypt($data, 'aes-256-cbc', $encryption_key, 0, $iv);
// The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)
return base64_encode($encrypted . '::' . $iv);
}
function my_decrypt($data, $key)
{
// Remove the base64 encoding from our key
$encryption_key = base64_decode($key);
// To decrypt, split the encrypted data from our IV - our unique separator used was "::"
list($encrypted_data, $iv) = explode('::', base64_decode($data), 2);
return openssl_decrypt($encrypted_data, 'aes-256-cbc', $encryption_key, 0, $iv);
}
$plaintext = 'rsmith@somecompany.com';
echo 'plaintext: ' . $plaintext . PHP_EOL;
$encryptionKey = base64_encode(32);
$ciphertext = my_encrypt($plaintext, $encryptionKey);
echo 'ciphertext: ' . $ciphertext . PHP_EOL;
$decryptedtext = my_decrypt($ciphertext, $encryptionKey);
echo 'decryptedtext: ' . $decryptedtext . PHP_EOL;
?>