在PHP中,加密一个非常短的字符串的最佳方法是什么?

12
我希望加密字符串,这些字符串可能只有三到四个字符,但长度可达二十个字符。哈希函数(md5sha1crypt等)不适用,因为我想要解密信息。mcrypt扩展具有一系列令人生畏的可能性。
有没有人有关于安全加密短字符串的最佳方法以及为什么的想法?有没有任何材料链接可以向业余程序员介绍实际的加密场景?

1
3-20个字符,这不是密码吧?单向加密几乎总是密码的更好选择。 - James Socol
8个回答

7

我喜欢使用GnuPG来加密服务器上需要加密的任何内容,然后在该服务器上或另一个服务器上(通常是我的情况)进行解密。这可以提供额外的安全级别,因为在我的情况下,加密服务器没有解密数据的密钥。它还可以更容易地进行手动解密。有几个针对各种编程语言的好封装器可用(另一个优势),其中一个是PHP的GnuPGP PHP Class


6

mcrypt是默认链接到大多数PHP构建中的。它包含了您可能需要的所有原语。如果不知道您加密的内容、威胁模型等方面的更多信息,很难对您使用哪种算法、操作模式等进行具体的建议。

有一件事可以确定:对于短文本字符串,使用唯一的随机初始化向量比以往任何时候都更为重要。否则,有人可以轻松地对加密数据发起各种攻击。


4
我强烈推荐Chris Kite的建议。如果不知道更多关于你正在做什么,为什么这样做以及需要保护的威胁,AES-128可能已经足够。使用对称加密的能力非常适用于一个独立的应用程序,它将是数据的解密器和加密器。正如Chris KiteArachnid所说,由于数据大小较小,建议填充数据并使用随机初始化向量。

更新: 至于为什么……如果数据足够小,并且可以预测IV,则可以通过生成每个明文与已知IV的密文的组合来暴力破解明文,并将其与捕获的密文匹配。简而言之,这就是彩虹表的工作原理。

现在,如果你打算在一台服务器上进行加密,然后在另一台服务器上进行解密,我会采用pdavis的建议。通过使用非对称方法,你可以将加密密钥与解密密钥分离。这样,如果加密数据的服务器被攻击,攻击者仍然无法解密数据。

如果可能的话,了解你加密用例将有助于社区更好地了解情况。正如我上面提到的,对可信威胁的适当理解是评估安全控制时的关键。


2

解密是不是很重要呢? 如果你只是想简单地混淆一下,可以使用ROT13。这是老派的做法。


7
你真的建议在加密帖子中使用 ROT13 吗? - Rich Bradshaw
6
天啊,伙计。你会阅读吗?“是否有人能解密这个无关紧要?” ROT13是一种有效的加密方式。破解它很简单,但并不总是重要的。我说得清楚了吧? - user1228

2
如果您想在应用程序中加密和解密数据,您最好使用对称密钥密码。AES是由NSA认证用于保护机密数据的对称块加密算法,是您的最佳选择。在www.phpaes.com上提供了一个纯PHP实现。
对于您的用途来说,AES128足够了。您需要使用带有随机初始化向量的CBC模式,否则相同的数据将始终产生相同的密文。
选择正确的加密算法是一个良好的第一步,但有许多因素构成了一个安全的系统,这些因素很难做到完美,例如密钥管理。有一些好的资源可供使用,例如Bruce Schneier的《应用密码学》和Ross Anderson的《安全工程》(可在线免费获取)。

2

我同意Chris Kite的观点 - 只需使用AES 128,这已经足够安全。

我不知道你的具体环境,但我猜测你正在通过互联网传输数据。

不要使用ECB模式,因为它总是会对相同的明文产生相同的加密结果。

CBC模式是最好的选择,不要忘记使用随机初始化向量。此向量必须与密文一起传输,并可以明文发送。

关于你的数据,由于AES是块加密算法,其输出始终是块大小的整数倍。如果你不想让观察者知道你的数据是短还是长,可以添加一些填充以将其扩展到最大预期大小。


0

任何单向加密算法,例如Blowfish都可以使用。 Blowfish快速且开放。您可以通过crypt()函数使用Blowfish。据我所知,没有特别适用于小字符串的加密算法。但需要注意的是,对这样的小字符串进行暴力破解将非常容易。也许您应该将字符串与“秘密”盐值一起加密以获得额外的安全性。


更正:crypt()版本不适合,因为它没有解密的方法。使用类似http://pear.php.net/package/Crypt_Blowfish的东西。这将为您提供额外的优势,无需担心安装额外的扩展。 - Roel

0

你可以使用一般的编程思路,而不依赖于内置的加密/解密功能。例如,创建一个函数并调用它。

function encryptstring($string) {

$string_length=strlen($string);
$encrychars=""; 
/**
*For each character of the given string generate the code
*/
for ($position = 0;$position<$string_length;$position++){        
    $key = (($string_length+$position)+1);
    $key = (255+$key) % 255;
    $get_char_to_be_encrypted = SUBSTR($string, $position, 1);
    $ascii_char = ORD($get_char_to_be_encrypted);
    $xored_char = $ascii_char ^ $key;  //xor operation
    $encrypted_char = CHR($xored_char);
    $encrychars .= $encrypted_char;
} 
/**
*Return the encrypted/decrypted string
*/
return $encrychars;
}

在链接页面上,需要包含要加密的ID。
   /**
    *While passing the unique value to a link
    *Do the following steps
    */

    $id=57;//or if you are fetching it automatically just pass it here
     /**
     *For more security multiply some value
     *You can set the multiplication value in config file
     */
     $passstring=$id*346244;
     $encrypted_string=encryptstring($passstring);
     $param=urlencode($encrypted_string);
     /**
     *Derive the url for the link
     */
     echo '<a href="target_file.php?aZ98#9A_KL='.$param.'">something</a>' ;

在链接被点击后打开的目标文件中

     /**
      *Retriving the value in the target file
      *Do the following steps
      */
      $fetchid=$_GET['aZ98#9A_KL'];
      $passstring=urldecode(stripslashes($fetchid));
      $decrypted_string= encryptstring($passstring);
      /**
       *Divide the decrypted value with the same value we used for the multiplication
       */
      $actual_id= $decrypted_string/346244;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接