Php 是什么导致了这些角色?

Php 是什么导致了这些角色?,php,encryption,encoding,Php,Encryption,Encoding,我有一个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(openss

我有一个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));
}
更新2 因此,在对数千封电子邮件进行大量测试后,
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;
}

我测试了您的加密和解密函数,它们的工作情况与预期一致,因此出现这种行为的原因似乎是您设备上的文件编码不同

特别是在读取CSV文件时,有时(windows)设备会更改编码,您会得到一些奇怪的字符,如您显示的字符。我的建议是使用另一种编码作为默认编码(ISO…)读取文件

我设置了一个实例,通过简单的字符串加密和解密“证明”了正确性:

结果很简单:

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;

?>


您发布的代码唯一的问题是字符串
完全可以在密文或IV中自然出现,从而破坏解码。只需在不使用分隔符的情况下连接它们,并使用已知的IV长度来分割字符串。至于为什么你的输出看起来像那样。。。可能是编码问题?您必须发布代码的其余部分和输入数据的代表性示例,我们可以使用这些示例来重现问题,尽管这可能会有问题,因为这是一封电子邮件address@Sammitch-我发布了更多的代码。不幸的是,我无法从我的列表中发布任何实际的电子邮件地址。我明白你所说的关于
-这可能是原因吗?原始CSV文件来自由第三方供应商维护的邮件列表导出
file-I
告诉我它被编码为
text/plain;字符集=utf-8
。我需要把它转换成其他的东西吗?“UTF-8”听起来不错,所以看起来好像initvector被某种方式改变了,所以一些字符被置乱了。尝试使用正确的电子邮件地址重新生成加密字符串,并将密文与csv文件中的字符串进行比较。