为了账号安全,请及时绑定邮箱和手机立即绑定

PHP AES加密/解密

/ 猿问

PHP AES加密/解密

开满天机 2019-07-31 18:40:33

PHP AES加密/解密

我在PHP中找到了en / decode字符串的示例。起初它看起来非常好,但它不会工作:-(


有谁知道问题是什么?


$Pass = "Passwort";

$Clear = "Klartext";


$crypted = fnEncrypt($Clear, $Pass);

echo "Encrypted: ".$crypted."</br>";


$newClear = fnDecrypt($crypted, $Pass);

echo "Decrypted: ".$newClear."</br>";


function fnEncrypt($sValue, $sSecretKey) {

    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, $sDecrypted, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));

}


function fnDecrypt($sValue, $sSecretKey) {

    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, base64_decode($sEncrypted), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)));

}

结果是:


加密: boKRNTYYNp7AiOvY1CidqsAn9wX4ufz/D9XrpjAOPk8=


解密: —‚(ÑÁ   ^ yË~F'¸®Ó–í    œð2Á_B‰Â—


查看完整描述

3 回答

?
森栏

$sDecrypted并且$sEncrypted 在您的代码中未定义。查看有效的解决方案(但不安全!):


停!

这个例子不安全!不要用它!


$Pass = "Passwort";$Clear = "Klartext";        $crypted = fnEncrypt($Clear, $Pass);echo "Encrypred: ".$crypted."</br>";$newClear = fnDecrypt($crypted, $Pass);echo "Decrypred: ".$newClear."</br>";        function fnEncrypt($sValue, $sSecretKey){
    return rtrim(
        base64_encode(
            mcrypt_encrypt(
                MCRYPT_RIJNDAEL_256,
                $sSecretKey, $sValue, 
                MCRYPT_MODE_ECB, 
                mcrypt_create_iv(
                    mcrypt_get_iv_size(
                        MCRYPT_RIJNDAEL_256, 
                        MCRYPT_MODE_ECB                    ), 
                    MCRYPT_RAND)
                )
            ), "\0"
        );}function fnDecrypt($sValue, $sSecretKey){
    return rtrim(
        mcrypt_decrypt(
            MCRYPT_RIJNDAEL_256, 
            $sSecretKey, 
            base64_decode($sValue), 
            MCRYPT_MODE_ECB,
            mcrypt_create_iv(
                mcrypt_get_iv_size(
                    MCRYPT_RIJNDAEL_256,
                    MCRYPT_MODE_ECB                ), 
                MCRYPT_RAND            )
        ), "\0"
    );}


查看完整回答
反对 回复 2019-07-31
?
千万里不及你

请使用现有的安全PHP加密库

除非您有破坏其他人的加密实现的经验,否则编写自己的加密通常是一个坏主意。

这里没有一个例子验证密文,这使得它们容易受到比特重写攻击。

如果你可以安装PECL扩展,libsodium甚至更好

<?php// PECL libsodium 0.2.1 and newer/**
 * Encrypt a message
 * 
 * @param string $message - message to encrypt
 * @param string $key - encryption key
 * @return string
 */function safeEncrypt($message, $key){
    $nonce = \Sodium\randombytes_buf(
        \Sodium\CRYPTO_SECRETBOX_NONCEBYTES    );

    return base64_encode(
        $nonce.
        \Sodium\crypto_secretbox(
            $message,
            $nonce,
            $key        )
    );}/**
 * Decrypt a message
 * 
 * @param string $encrypted - message encrypted with safeEncrypt()
 * @param string $key - encryption key
 * @return string
 */function safeDecrypt($encrypted, $key){   
    $decoded = base64_decode($encrypted);
    $nonce = mb_substr($decoded, 0, \Sodium\CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
    $ciphertext = mb_substr($decoded, \Sodium\CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');

    return \Sodium\crypto_secretbox_open(
        $ciphertext,
        $nonce,
        $key    );}

然后测试一下:

<?php// This refers to the previous code block.require "safeCrypto.php"; // Do this once then store it somehow:$key = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_KEYBYTES);$message = 'We are all living in a yellow submarine';$ciphertext = safeEncrypt($message, $key);$plaintext = safeDecrypt($ciphertext, $key);var_dump($ciphertext);var_dump($plaintext);

这可以在您将数据传递到客户端的任何情况下使用(例如,没有服务器端存储的会话的加密cookie,加密的URL参数等),并且具有相当高的确定性,即最终用户无法破译或可靠地篡改用它。

由于libsodium是跨平台的,因此也可以更轻松地与PHP通信,例如Java applet或本机移动应用程序。


注意:如果您特别需要将libsodium提供的加密cookie添加到您的应用程序,我的雇主Paragon Initiative Enterprises正在开发一个名为Halite的库,它可以为您完成所有这些工作。


查看完整回答
反对 回复 2019-07-31
?
慕哥9229398


如果您不想对 15行代码中可解决的内容使用重依赖,请使用内置的OpenSSL函数。大多数PHP安装都附带OpenSSL,它在PHP中提供快速,兼容和安全的AES加密。嗯,只要您遵循最佳实践,它就是安全的。


以下代码:


在CBC模式下使用AES256

与其他AES实现兼容,但不兼容mcrypt,因为mcrypt使用PKCS#5而不是PKCS#7。

使用SHA256从提供的密码生成密钥

生成加密数据的hmac哈希以进行完整性检查

为每条消息生成随机IV

将IV(16字节)和散列(32字节)预先添加到密文

应该非常安全

IV是一个公共信息,每个消息都需要随机。哈希确保数据未被篡改。


function encrypt($plaintext, $password) {

    $method = "AES-256-CBC";

    $key = hash('sha256', $password, true);

    $iv = openssl_random_pseudo_bytes(16);


    $ciphertext = openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv);

    $hash = hash_hmac('sha256', $ciphertext, $key, true);


    return $iv . $hash . $ciphertext;

}


function decrypt($ivHashCiphertext, $password) {

    $method = "AES-256-CBC";

    $iv = substr($ivHashCiphertext, 0, 16);

    $hash = substr($ivHashCiphertext, 16, 32);

    $ciphertext = substr($ivHashCiphertext, 48);

    $key = hash('sha256', $password, true);


    if (hash_hmac('sha256', $ciphertext, $key, true) !== $hash) return null;


    return openssl_decrypt($ciphertext, $method, $key, OPENSSL_RAW_DATA, $iv);

}

用法:


$encrypted = encrypt('Plaintext string.', 'password'); // this yields a binary string


echo decrypt($encrypted, 'password');

// decrypt($encrypted, 'wrong password') === null


查看完整回答
反对 回复 2019-07-31

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信