我的应用程序(显然)使用唯一ID来区分记录。此UID在URL(例如./examplepage.php?UID=$example_int
)等中传递。
虽然我明显有服务器端验证以确保客户端不访问其他客户端的数据,但我是否可以在PHP中使用双向加密方法来仅传递加密的UID(例如{{1} }),进一步减少任何人思考“嘿,如果我增加这个整数会发生什么?”的机会。
TIA。
答案 0 :(得分:94)
PHP 5.3引入了一种非常易于使用的新加密方法:openssl_encrypt
和openssl_decrypt
。这里没有详细记录,所以这里有一个简单的例子:
$textToEncrypt = "My super secret information.";
$encryptionMethod = "AES-256-CBC"; // AES is used by the U.S. gov't to encrypt top secret documents.
$secretHash = "25c6c7ff35b9979b151f2136cd13b0ff";
//To encrypt
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash);
//To Decrypt
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash);
//Result
echo "Encrypted: $encryptedMessage <br>Decrypted: $decryptedMessage";
我选择了256-AES,因为它坚固而快速。它被美国政府采用来加密绝密文件。考虑到机器和软件,它很快。以下是可用加密方法的列表:
AES-128-CBC,AES-128-CFB,AES-128-CFB1,AES-128-CFB8,AES-128-ECB,AES-128-OFB,AES-192-CBC,AES-192-CFB ,AES-192-CFB1,AES-192-CFB8,AES-192-ECB,AES-192-OFB,AES-256-CBC,AES-256-CFB,AES-256-CFB1,AES-256-CFB8,AES -256-ECB,AES-256-OFB,BF-CBC,BF-CFB,BF-ECB,BF-OFB,CAMELLIA-128-CBC,CAMELLIA-128-CFB,CAMELLIA-128-CFB1,CAMELLIA-128-CFB8 ,CAMELLIA-128-ECB,CAMELLIA-128-OFB,CAMELLIA-192-CBC,CAMELLIA-192-CFB,CAMELLIA-192-CFB1,CAMELLIA-192-CFB8,CAMELLIA-192-ECB,CAMELLIA-192-OFB,CAMELLIA -256-CBC,CAMELLIA-256-CFB,CAMELLIA-256-CFB1,CAMELLIA-256-CFB8,CAMELLIA-256-ECB,CAMELLIA-256-OFB,CAST5-CBC,CAST5-CFB,CAST5-ECB,CAST5-OFB ,DES-CBC,DES-CFB,DES-CFB1,DES-CFB8,DES-ECB,DES-EDE,DES-EDE-CBC,DES-EDE-CFB,DES-EDE-OFB,DES-EDE3,DES-EDE3 -CBC,DES-EDE3-CFB,DES-EDE3-CFB1,DES-EDE3-CFB8,DES-EDE3-OFB,DES-OFB,DESX-CBC,RC2-40-CBC,RC2-64-CBC,RC2-CBC ,RC2-CFB,RC2-ECB,RC2-OFB,RC4,RC4-40,SEED-CBC,SEED-CFB,SEED-ECB,SEED-OFB,aes-128-cbc,aes-128-cfb,aes-128 -cfb1,ae s-128-cfb8,aes-128-ecb,aes-128-ofb,aes-192-cbc,aes-192-cfb,aes-192-cfb1,aes-192-cfb8,aes-192-ecb,aes- 192-ofb,aes-256-cbc,aes-256-cfb,aes-256-cfb1,aes-256-cfb8,aes-256-ecb,aes-256-ofb,bf-cbc,bf-cfb,bf- ecb,bf-ofb,camellia-128-cbc,camellia-128-cfb,camellia-128-cfb1,camellia-128-cfb8,camellia-128-ecb,camellia-128-ofb,camellia-192-cbc,camellia- 192-cfb,山茶花-192-cfb1,山茶花-192-cfb8,山茶花-192-ecb,山茶花-192-ofb,山茶花-256-cbc,山茶花-256-cfb,山茶花-256-cfb1,山茶花-256- cfb8,camellia-256-ecb,camellia-256-ofb,cast5-cbc,cast5-cfb,cast5-ecb,cast5-ofb,des-cbc,des-cfb,des-cfb1,des-cfb8,des-ecb, des-ede,des-ede-cbc,des-ede-cfb,des-ede-ofb,des-ede3,des-ede3-cbc,des-ede3-cfb,des-ede3-cfb1,des-ede3-cfb8, des-ede3-ofb,des-ofb,desx-cbc,rc2-40-cbc,rc2-64-cbc,rc2-cbc,rc2-cfb,rc2-ecb,rc2-ofb,rc4,rc4-40,seed- cbc,seed-cfb,seed-ecb,seed-ofb
重要更新!!!
感谢Hobo和Jorwin在PHP 5.3.3中指出&gt;有一个新参数可以使这个功能更安全一些。
Jorwin在his comment中引用了这个链接,这是一个适用的摘录:
在5.3.3中,他们添加了一个新参数
string $iv
(初始化 vector)真实参数是:string openssl_encrypt ( string $data , string $method , string $password, bool $raw_output = false, string $iv )
如果缺少
$iv
,则会发出警告:“使用空的初始化向量(iv)可能不安全,不建议使用”。如果
$iv
太短,另一个警告:“IV传递的长度只有3个字节,密码期望IV精确为8个字节,填充为\ 0”中应使用相同的IV
openssl_decrypt()
答案 1 :(得分:28)
您不需要双向加密 - 加密用于维护保密,但您真正需要的是真实性。
HMAC(基本上是键控哈希)是获取加密真实性的一种方法。使用只有服务器知道的密钥,使用UID的HMAC(PHP具有HMAC implementation)来附加UID。在每个请求开始时,请检查HMAC。
基本上,使用正确的工具来完成正确的工作。
答案 2 :(得分:3)
虽然PHP支持许多双向散列算法,但我不认为它在这个例子中有用。你需要做的是:
但如果你的心脏被设置为散列,只需选择其中一种算法provided。
答案 3 :(得分:2)
答案 4 :(得分:0)
首先,encrypting URL parameters is usually a bad idea和单独的查找(基于CSPRNG生成的索引CHAR
列)对99.9%的用例更好。
话虽如此:是的,您可以使用OpenSSL扩展(don't use mcrypt)来加密数据like espradley suggested,但我会提醒您不要只停止加密。
如果您信任具有密文的最终用户,则Encryption without message authentication is dangerous,尤其是。
因此,解决方案是使用authenticated encryption,可以使用libsodium, available on PECL轻松访问。
如果由于某种原因无法安装PECL扩展,则有两个PHP库可供选择:defuse/php-encryption和zend-crypt。它们都提供符合标准的认证加密,并且它们都是安全的(对于它的价值,我经常在PHP中执行code audits for cryptography implementations,我不是只是互联网上的一些随机的人)。
答案 5 :(得分:0)
在PHP中,可以使用称为OpenSSL函数的加密扩展之一对字符串进行加密和解密。
openssl_encrypt()函数:openssl_encrypt()函数用于加密数据。
语法如下:
string openssl_encrypt(字符串$ data,字符串$ method,字符串$ key, $ options = 0,字符串$ iv,字符串$ tag = NULL, 字符串$ aad,int $ tag_length = 16)
参数如下:
$ data::它包含需要加密的字符串或数据。
$ method::使用openssl_get_cipher_methods()函数采用加密方法。
$ key:。它拥有加密密钥。
$ options :它保存标志OPENSSL_RAW_DATA和 OPENSSL_ZERO_PADDING。
$ iv::它保存初始化向量,该初始化向量不是NULL。
$ tag::它包含使用AEAD密码模式(GCM或CCM)时通过引用传递的身份验证标签。
$ aad::它包含其他身份验证数据。
$ tag_length::它保存身份验证标签的长度。对于GCM模式,身份验证标签的长度在4到16之间。
返回值::成功时返回加密的字符串,失败时返回FALSE。
openssl_decrypt()函数openssl_decrypt()函数用于解密数据。
语法如下:
string openssl_decrypt(字符串$ data,字符串$ method,字符串$ key, int $ options = 0,字符串$ iv,字符串$ tag,字符串$ aad)
参数如下:
$ data::它包含需要加密的字符串或数据。
$ method::使用openssl_get_cipher_methods()函数采用加密方法。
$ key:。它拥有加密密钥。
$ options :它保存标志OPENSSL_RAW_DATA和OPENSSL_ZERO_PADDING的按位析取。
$ iv:它保存初始化向量,该初始化向量不是NULL。
$ tag::它使用AEAD密码模式(GCM或CCM)保存身份验证标签。身份验证失败时,openssl_decrypt()将返回FALSE。
$ aad::它包含其他身份验证数据。
返回值::成功时返回解密的字符串,失败时返回FALSE。
方法:首先声明一个字符串并将其存储到变量中,然后使用openssl_encrypt()函数加密给定的字符串,然后使用openssl_decrypt()函数解密给定的字符串。
您可以在以下位置找到示例: https://www.geeksforgeeks.org/how-to-encrypt-and-decrypt-a-php-string/
答案 6 :(得分:-3)
在ID旁边放置一个哈希以确保它的安全性,或者用额外的数据填充ID,或者甚至将ID转换为十六进制都可以很好地工作。