Dav*_*eh0 4 php security encryption pii
我需要通过查询字符串传递一个值以显示在我的页面上。该值必须加密,因为它包含一些供查看页面的用户使用的 PII。并且为了让用户可读,它需要在显示时能够被解密。
我使用PHP和研究迄今已使我openssl_encrypt和openssl_decrypt这些2个代码资源一起:
我非常喜欢#1,因为iv它实际附加到返回的加密字符串的方式。这使我们不必将 an 存储iv为常量,并且能够在每次调用函数时生成一个新的。这似乎比使用相同的更安全对我key和iv每一次。真的吗?如果是这样,除了痛苦的显而易见的原因之外,我是否应该知道任何原因?. 我不喜欢的是,我认为将iv和key与一个字符/字符串(在这种情况下::)连接起来,可以在其他潜在的密码文本或iv成了问题。使用这种方法,在尝试加密 7000 多个电子邮件地址时,其中一半多一点的结果是这些奇怪的字符,???6CT?其中包括)在解码字符串中,从而破坏了它。
#2 很棒,因为它有效!!我还没有找到可以破坏它的字符串……尤其是在我的电子邮件列表中。但是如上所述,这需要。在iv和key 永远是相同的值,并存储在一个变量的地方。这似乎是一个很小的维护问题,但更多的是安全问题。
所以我做了更多的阅读/思考并想出了这个工作示例- 这是代码:
<?php
// generate key with base64_encode(openssl_random_pseudo_bytes(32);
// and save it in a constant.
define('ENCRYPT_KEY_1', 'CuH8WPfXzMj0xRWybHjssWJ+IhTDqL5w0OD9+zXFloA=');
function encrypt_decrypt($action, $string) {
$output = false;
$encrypt_method = "AES-256-CBC";
$key = ENCRYPT_KEY_1;
$ivLen = openssl_cipher_iv_length($encrypt_method);
/**
* the key was generated with 32 pseudo-bytes and then base64Encod()-ed.
* Not sure of the reason for encoding - just decoding in case it's necessary.
*
* Thoughts?
* **/
$key = base64_decode($key);
if ( $action == 'encrypt' ) {
/**
* "AES-256-CBC" expects a 16-byte string - create an 8-byte string to be
* converted to a 16-byte hex before being used as the initialization vector
* TLDR" in order to end up with 16-bytes to feed to openssl_random_pseudo_bytes,
* divide initial length in half as the hex value will double it
* */
$iv = openssl_random_pseudo_bytes($ivLen/2);
$iv = bin2hex($iv);
$tmp_data_str_in = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($tmp_data_str_in . $iv);
} else if( $action == 'decrypt' ) {
$data_str_in = base64_decode($string);
// This time, rather than generating one, we get the iv (converted to hex)
// by grabbing the last 16 characters of the concatenation of the 2 that happened
// during encryption.
$iv = substr($data_str_in, -$ivLen);
// And now we just grab everything BUT the last 16 characters. We'll
// run openssl_decrypt and return a copy of the original input
$encrypted_txt_str = substr($data_str_in, 0, strlen($data_str_in)-$ivLen);
// Notice we are returning the encrypted value of a string consisting of
// encoded versions of the input text and a random `IV` - we'll grab the `IV`
// from it later in order to decrypt later.
$output = openssl_decrypt($encrypted_txt_str, $encrypt_method, $key, 0, $iv);
}
return $output;
}
$plain_txt = "memyselfandi@i.me";
echo "Plain Text = " .$plain_txt. "\n";
$encrypted_txt = encrypt_decrypt('encrypt', $plain_txt);
echo "Encrypted Text = " .$encrypted_txt. "\n";
$decrypted_txt = encrypt_decrypt('decrypt', $encrypted_txt);
echo "Decrypted Text = " .$decrypted_txt. "\n";
if ( $plain_txt === $decrypted_txt ) echo "SUCCESS";
else echo "FAILED";
echo "\n";
?>
Run Code Online (Sandbox Code Playgroud)
所以我想我的主要问题是:
iv在执行函数时生成的动态的解决方案比iv提前定义静态并用于每个加密更安全?如果没有,我错过了什么?print "<li>Email: " . encrypt_decrypt('decrypt', my_sanitize_fxn($_GET['ue']) . "</li">;我猜这将是FAR更好的加密的东西是不是PII(如在数据库中的用户的唯一ID),并通过查询字符串发送,然后解密该值,并用它来查找自己的电子邮件地址与数据库查询。尽管我最终可能会在他结束时采取这种方式,但我们只能说目前正在发挥作用的因素(对此进行解释会使这个问题离主题太远)阻止它成为一个远程可行的选择。
我认为了解我在这里得到的东西会很好地延续到最终的解决方案中。除了对我在整个过程中提出的一些正式问题的回答之外,我很想听听任何做得特别差或做得特别好的事情,或者只是一般性评论。
预先感谢您愿意分享的任何智慧。
很抱歉我懒得将我的示例应用到您的代码中,但它应该不会那么复杂,因为以下代码是具有随机 IV 的 AES GCM 256 字符串加密的完整示例。将 IV 和标签添加到密文中,然后进行 Base64 编码。
请注意,代码没有任何错误处理,仅用于教育目的!不要使用静态密钥进行加密。
输出:
Sample AES GCM 256 string encryption
Please note that this code does not have any error handling and is for educational purpose only
Do NOT use static keys for encryption !
plaintext: The quick brown fox jumps over the lazy dog
encrypt: jemvFuwhIaUYx49d1nap6uKz8wMIorvQuRD/PGt+SYhFt8iaK1fiqAf8CjWtVNYqFZATStgq2XQuUAhbnhMtpzHDPN7oUFo=
decrypt: The quick brown fox jumps over the lazy dog
Run Code Online (Sandbox Code Playgroud)
代码:
<?php
function encrypt($encryptionKey, $data) {
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-gcm'));
$encrypted = openssl_encrypt($data, 'aes-256-gcm', $encryptionKey, OPENSSL_RAW_DATA, $iv, $tag);
return base64_encode($iv . $tag . $encrypted);
}
function decrypt($encryptionKey, $data) {
$c = base64_decode($data);
$ivlen = openssl_cipher_iv_length($cipher="AES-256-GCM");
$iv = substr($c, 0, $ivlen);
$tag = substr($c, $ivlen, $taglen=16);
$ciphertext_raw = substr($c, $ivlen+$taglen);
return openssl_decrypt($ciphertext_raw, 'aes-256-gcm', $encryptionKey, OPENSSL_RAW_DATA, $iv, $tag);
}
echo 'Sample AES GCM 256 string encryption' . PHP_EOL;
echo 'Please note that this code does not have any error handling and is for educational purpose only' . PHP_EOL;
echo 'Do NOT use static keys for encryption !'. PHP_EOL . PHP_EOL;
$plaintext = 'The quick brown fox jumps over the lazy dog';
$key = '12345678901234567890123456789012'; // 32 bytes = 256 bit key
echo 'plaintext: ' . $plaintext .PHP_EOL;
$encrypt = encrypt($key, $plaintext);
echo 'encrypt: ' . $encrypt . PHP_EOL;
$decrypt = decrypt($key, $encrypt);
echo 'decrypt: ' . $decrypt . PHP_EOL;
?>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
497 次 |
| 最近记录: |