【问题标题】:PHP Two Way EncryptionPHP 双向加密
【发布时间】:2013-08-04 20:59:58
【问题描述】:

我需要能够加密和解密变量,但是我还需要知道解密是否成功。在我的代码中,当我在解密之前将 $string 变量更改为其他值时,我会收到随机字符。

function encrypt($string) {
    $key = 'password';
    $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key))));
    return $encrypted;
}
function decrypt($encrypted) {
    $key = 'password';
    $decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encrypted), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
    return $decrypted;
}

$string = 'Hello world.';
if (encrypt($string)) {
    $string = encrypt($string);
    echo $string;
    echo '<br>';
}

if (decrypt($string)) {
    $string = decrypt($string);
    echo $string;
    echo '<br>';
}

是否可以检测到解密失败? 谢谢。

【问题讨论】:

  • 加密“失败”是什么意思?
  • 当函数由于在解密前更改$string变量而输出随机字符时。我需要能够检测到这一点。
  • 你为什么要更改 $string 变量?
  • 如果你担心你的 $string 变量被其他代码污染,那么你应该为你的数据创建一个类并将你的变量设置为私有,这样你的代码之外的任何东西都不能修改它。但前提是它保证了整个类,否则将您的变量重命名为真正独特的东西,不太可能在代码的其他部分中使用。
  • 您当前没有使用 AES,您正在使用 Rijndael,其 块大小 为 256 位,密钥大小为 128 位。 MD5 用作基于密码的密钥派生机制,但事实并非如此。 IV 不是随机的,这是 CBC 编码的要求,至少如果您想重用密钥。

标签: php encryption


【解决方案1】:

检测密文篡改的最佳方法是在密文上添加 MAC(消息验证码)。这是由密钥生成的签名。用于此的密钥应该与用于执行加密的密钥不同。一种方法是在主密钥上使用 KDF(密钥派生函数)来生成两个密钥。

或者,也可以使用经过身份验证的密码,例如 GCM(伽罗瓦计数器模式)。

MAC 或认证密码生成的认证数据称为认证标签。


您试图实现的目标的合理实现似乎嵌入在 Zend 框架中:

http://www.zimuel.it/en/english-cryptography-made-easy-with-zend-framework/

不要忘记将盐与密文一起检索和存储(加密后调用getSalt(),解密时使用setSalt())。请注意,作者经常混淆盐和 IV 这两个词,这不是一个好兆头。

免责声明:我没有通读该组件部署的对称密码,也没有以任何方式测试过代码。

【讨论】:

    猜你喜欢
    • 2012-03-15
    • 2011-04-23
    • 2011-04-15
    • 2017-06-02
    • 2012-01-16
    • 2012-03-04
    • 2018-11-27
    • 2010-09-07
    • 1970-01-01
    相关资源
    最近更新 更多