PHP中的双向加密

时间:2009-09-07 22:12:18

标签: php encryption

我的应用程序(显然)使用唯一ID来区分记录。此UID在URL(例如./examplepage.php?UID=$example_int)等中传递。

虽然我明显有服务器端验证以确保客户端不访问其他客户端的数据,但我是否可以在PHP中使用双向加密方法来仅传递加密的UID(例如{{1} }),进一步减少任何人思考“嘿,如果我增加这个整数会发生什么?”的机会。

TIA。

7 个答案:

答案 0 :(得分:94)

PHP 5.3引入了一种非常易于使用的新加密方法:openssl_encryptopenssl_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”

     

openssl_decrypt()

中应使用相同的IV

答案 1 :(得分:28)

您不需要双向加密 - 加密用于维护保密,但您真正需要的是真实性

HMAC(基本上是键控哈希)是获取加密真实性的一种方法。使用只有服务器知道的密钥,使用UID的HMAC(PHP具有HMAC implementation)来附加UID。在每个请求开始时,请检查HMAC。

基本上,使用正确的工具来完成正确的工作。

答案 2 :(得分:3)

虽然PHP支持许多双向散列算法,但我不认为它在这个例子中有用。你需要做的是:

  1. 按提供的ID
  2. 从存储中加载行
  3. 检查该行的所有者是否为经过身份验证的用户,如果没有抛出异常并通知用户不再执行此操作
  4. 但如果你的心脏被设置为散列,只需选择其中一种算法provided

答案 3 :(得分:2)

对于双向加密检查mcrypt,或者您更喜欢纯实现phpseclib

答案 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-encryptionzend-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转换为十六进制都可以很好地工作。