用于通过URL传递变量的php双向加密
好的。。。说到点子上 我有一个电子邮件快照程序,它可以发送数千封电子邮件,每封邮件都带有用于通过URL传递变量的php双向加密,php,url,encryption,get,two-way,Php,Url,Encryption,Get,Two Way,好的。。。说到点子上 我有一个电子邮件快照程序,它可以发送数千封电子邮件,每封邮件都带有str_replace()merge字段(被记录集中的行值替换的字段) 其中一个重要的部分是我能够在open上跟踪这些邮件,所以我包含了一个服务器端生成的像素 <img src="http://...trace.php?email=<<<EMAIL>>>" alt="" height="1" width="1"> >“alt=”“height=“1”width
str_replace()
merge字段(被记录集中的行值替换的字段)
其中一个重要的部分是我能够在open上跟踪这些邮件,所以我包含了一个服务器端生成的像素
<img src="http://...trace.php?email=<<<EMAIL>>>" alt="" height="1" width="1">
>“alt=”“height=“1”width=“1”>
str_replace()
将
替换为唯一的真实电子邮件地址
trace.php
文件读取$\u GET['email']
并记录或发送邮件确认
我的问题是安全:)
我想使用双向加密,以便URL中发送的$\u GET
变量是一封加密的电子邮件。然后trace.php文件需要对其进行解密
由于它是在URL中发送的,所以它必须是ASCII格式,否则在解密之前会损坏
我不能使用openssl\u encrypt()
&openssl\u decrypt()
,我必须使用PHP5.2.0(不要对我谩骂!)
任何帮助都将不胜感激!!虽然您收到的许多评论提供了解决问题的其他有效方法,例如带有主键的电子邮件地址表,但我的立场是,解决问题的最佳方法是您最初打算采用的方法:包括在查询URL中加密的电子邮件地址 我觉得这样更好,因为:
- 计算电子邮件地址不需要数据库访问。对于高延迟请求,数据库瓶颈通常是最大的问题
- 加密意味着每次加密时,同一个电子邮件地址将产生不同的IV/密文对。因此,如果您在不同的时间发送多封电子邮件(例如,两次不同的营销活动),URL每次都会不同。这可能不会产生影响,但它确实提供了安全优势,因为攻击者不能通过访问URL“假装”电子邮件已被打开
openssl*
,那么就升级你的PHP版本。永远不要使用mcrypt
函数。它们因某种原因被弃用。你可能需要ex encode而不是base64编码电子邮件地址,如下例所示
<?php
define("ALGORITHM_NAME", "aes-128-gcm");
define("ALGORITHM_NONCE_SIZE", 12);
define("ALGORITHM_TAG_SIZE", 16);
define("ALGORITHM_KEY_SIZE", 16);
define("PBKDF2_NAME", "sha256");
define("PBKDF2_SALT_SIZE", 16);
define("PBKDF2_ITERATIONS", 32767);
function encryptString($plaintext, $password) {
// Generate a 128-bit salt using a CSPRNG.
$salt = random_bytes(PBKDF2_SALT_SIZE);
// Derive a key.
$key = hash_pbkdf2(PBKDF2_NAME, $password, $salt, PBKDF2_ITERATIONS, ALGORITHM_KEY_SIZE, true);
// Encrypt and prepend salt and return as base64 string.
return base64_encode($salt . encrypt($plaintext, $key));
}
function decryptString($base64CiphertextAndNonceAndSalt, $password) {
// Decode the base64.
$ciphertextAndNonceAndSalt = base64_decode($base64CiphertextAndNonceAndSalt);
// Retrieve the salt and ciphertextAndNonce.
$salt = substr($ciphertextAndNonceAndSalt, 0, PBKDF2_SALT_SIZE);
$ciphertextAndNonce = substr($ciphertextAndNonceAndSalt, PBKDF2_SALT_SIZE);
// Derive the key.
$key = hash_pbkdf2(PBKDF2_NAME, $password, $salt, PBKDF2_ITERATIONS, ALGORITHM_KEY_SIZE, true);
// Decrypt and return result.
return decrypt($ciphertextAndNonce, $key);
}
function encrypt($plaintext, $key) {
// Generate a 96-bit nonce using a CSPRNG.
$nonce = random_bytes(ALGORITHM_NONCE_SIZE);
// Encrypt and prepend nonce.
$ciphertext = openssl_encrypt($plaintext, ALGORITHM_NAME, $key, OPENSSL_RAW_DATA, $nonce, $tag);
return $nonce . $ciphertext . $tag;
}
function decrypt($ciphertextAndNonce, $key) {
// Retrieve the nonce and ciphertext.
$nonce = substr($ciphertextAndNonce, 0, ALGORITHM_NONCE_SIZE);
$ciphertext = substr($ciphertextAndNonce, ALGORITHM_NONCE_SIZE, strlen($ciphertextAndNonce) - ALGORITHM_NONCE_SIZE - ALGORITHM_TAG_SIZE);
$tag = substr($ciphertextAndNonce, strlen($ciphertextAndNonce) - ALGORITHM_TAG_SIZE);
// Decrypt and return result.
return openssl_decrypt($ciphertext, ALGORITHM_NAME, $key, OPENSSL_RAW_DATA, $nonce, $tag);
}
?>
为什么不生成一个令牌,然后在服务器端将其与电子邮件地址关联?任何加密的内容都可以解密,因此仍然代表一个攻击面。通过使发送的值成为无意义的随机垃圾,完全删除所有攻击面。您只需存储该垃圾即可我也站在你这边。@RichardOwens是的,这就是我(我认为@deceze)意思是。不,这不会太难。散列电子邮件,将散列和电子邮件存储在表中。当trace.php被访问时,查找散列并获取电子邮件。一个简单的数字id本质上是没有意义的。任何人看到URL中的id=5
都绝对没有关于连接到哪个电子邮件的信息。感谢您在这里所做的努力。回复很遗憾,我不能在这里调用一些预定义函数,包括random_bytes()或hash_pbkdf2()。您需要升级您的PHP版本。在没有这些函数的情况下实现此功能所需的工作量远远超过升级您的PHP版本所需的工作量。我很快就得出了这个结论!!我很抱歉不能充分利用您的辛勤工作。太好了。