我的意思是:

Original String + Salt or Key --> Encrypted String
Encrypted String + Salt or Key --> Decrypted (Original String)

也许是这样的:

"hello world!" + "ABCD1234" --> Encrypt --> "2a2ffa8f13220befbe30819047e23b2c" (may be, for e.g)
"2a2ffa8f13220befbe30819047e23b2c" --> Decrypt with "ABCD1234" --> "hello world!"

在PHP中,如何做到这一点?

尝试使用Crypt_Blowfish,但它不适合我。


当前回答

更新

PHP 7就绪版本。它使用了PHP OpenSSL库中的openssl_encrypt函数。

class Openssl_EncryptDecrypt {
    function encrypt ($pure_string, $encryption_key) {
        $cipher     = 'AES-256-CBC';
        $options    = OPENSSL_RAW_DATA;
        $hash_algo  = 'sha256';
        $sha2len    = 32;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext_raw = openssl_encrypt($pure_string, $cipher, $encryption_key, $options, $iv);
        $hmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
        return $iv.$hmac.$ciphertext_raw;
    }
    function decrypt ($encrypted_string, $encryption_key) {
        $cipher     = 'AES-256-CBC';
        $options    = OPENSSL_RAW_DATA;
        $hash_algo  = 'sha256';
        $sha2len    = 32;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = substr($encrypted_string, 0, $ivlen);
        $hmac = substr($encrypted_string, $ivlen, $sha2len);
        $ciphertext_raw = substr($encrypted_string, $ivlen+$sha2len);
        $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $encryption_key, $options, $iv);
        $calcmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
        if(function_exists('hash_equals')) {
            if (hash_equals($hmac, $calcmac)) return $original_plaintext;
        } else {
            if ($this->hash_equals_custom($hmac, $calcmac)) return $original_plaintext;
        }
    }
    /**
     * (Optional)
     * hash_equals() function polyfilling.
     * PHP 5.6+ timing attack safe comparison
     */
    function hash_equals_custom($knownString, $userString) {
        if (function_exists('mb_strlen')) {
            $kLen = mb_strlen($knownString, '8bit');
            $uLen = mb_strlen($userString, '8bit');
        } else {
            $kLen = strlen($knownString);
            $uLen = strlen($userString);
        }
        if ($kLen !== $uLen) {
            return false;
        }
        $result = 0;
        for ($i = 0; $i < $kLen; $i++) {
            $result |= (ord($knownString[$i]) ^ ord($userString[$i]));
        }
        return 0 === $result;
    }
}

define('ENCRYPTION_KEY', '__^%&Q@$&*!@#$%^&*^__');
$string = "This is the original string!";

$OpensslEncryption = new Openssl_EncryptDecrypt;
$encrypted = $OpensslEncryption->encrypt($string, ENCRYPTION_KEY);
$decrypted = $OpensslEncryption->decrypt($encrypted, ENCRYPTION_KEY);

其他回答

不要做什么

警告: 这个答案使用了欧洲央行。ECB不是一个加密模式,它只是一个构建模块。使用这个答案中演示的ECB实际上并不能安全地加密字符串。不要在代码中使用ECB。请参阅Scott的回答以获得一个好的解决方案。

我自己弄到的。实际上我在谷歌上找到了一些答案,只是修改了一些东西。然而,结果是完全不安全的。

<?php
define("ENCRYPTION_KEY", "!@#$%^&*");
$string = "This is the original data string!";

echo $encrypted = encrypt($string, ENCRYPTION_KEY);
echo "<br />";
echo $decrypted = decrypt($encrypted, ENCRYPTION_KEY);

/**
 * Returns an encrypted & utf8-encoded
 */
function encrypt($pure_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
    return $encrypted_string;
}

/**
 * Returns decrypted original string
 */
function decrypt($encrypted_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH, $encryption_key, $encrypted_string, MCRYPT_MODE_ECB, $iv);
    return $decrypted_string;
}
?>

对于Laravel框架

如果您正在使用Laravel框架,那么使用内部函数加密和解密将更加容易。

$string = 'Some text to be encrypted';
$encrypted = \Illuminate\Support\Facades\Crypt::encrypt($string);
$decrypted_string = \Illuminate\Support\Facades\Crypt::decrypt($encrypted);

var_dump($string);
var_dump($encrypted);
var_dump($decrypted_string);

注意:请确保在中设置16,24或32个字符的随机字符串 config/app.php文件的关键选项。否则,加密值 不会有安全感。

历史注释:这是在PHP4时代编写的。这就是我们现在所说的“遗留代码”。

出于历史原因,我留下了这个答案——但有些方法现在已弃用,DES加密方法不是推荐的实践,等等。

我没有更新这段代码有两个原因:1)我不再在PHP中手工使用加密方法,2)这段代码仍然达到了预期的目的:演示如何在PHP中进行加密的最简单的概念。

如果你发现类似简单的“PHP加密傻瓜”的源代码,可以让人们在10-20行代码或更少的代码中开始,请在评论中告诉我。

除此之外,请欣赏这个早期PHP4极简加密答案的经典集。


理想情况下,您已经或能够访问mcrypt PHP库,因为它确实很受欢迎,对各种任务非常有用。下面是不同类型的加密和一些示例代码

//Listing 3: Encrypting Data Using the mcrypt_ecb Function 

<?php 
echo("<h3> Symmetric Encryption </h3>"); 
$key_value = "KEYVALUE"; 
$plain_text = "PLAINTEXT"; 
$encrypted_text = mcrypt_ecb(MCRYPT_DES, $key_value, $plain_text, MCRYPT_ENCRYPT); 
echo ("<p><b> Text after encryption : </b>"); 
echo ( $encrypted_text ); 
$decrypted_text = mcrypt_ecb(MCRYPT_DES, $key_value, $encrypted_text, MCRYPT_DECRYPT); 
echo ("<p><b> Text after decryption : </b>"); 
echo ( $decrypted_text ); 
?> 

一些警告:

1)当单向哈希可以使用时,永远不要使用可逆或“对称”加密。

2) If the data is truly sensitive, like credit card or social security numbers, stop; you need more than any simple chunk of code will provide, but rather you need a crypto library designed for this purpose and a significant amount of time to research the methods necessary. Further, the software crypto is probably <10% of security of sensitive data. It's like rewiring a nuclear power station - accept that the task is dangerous and difficult and beyond your knowledge if that's the case. The financial penalties can be immense, so better to use a service and ship responsibility to them.

3)任何一种容易实现的加密,如这里所列,都可以合理地保护你想要避免被窥探或限制意外/故意泄露的情况下暴露的轻度重要信息。但鉴于密钥是如何以纯文本形式存储在web服务器上的,如果他们能获得数据,他们就能获得解密密钥。

尽管如此,玩得开心吧。

更新

PHP 7就绪版本。它使用了PHP OpenSSL库中的openssl_encrypt函数。

class Openssl_EncryptDecrypt {
    function encrypt ($pure_string, $encryption_key) {
        $cipher     = 'AES-256-CBC';
        $options    = OPENSSL_RAW_DATA;
        $hash_algo  = 'sha256';
        $sha2len    = 32;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext_raw = openssl_encrypt($pure_string, $cipher, $encryption_key, $options, $iv);
        $hmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
        return $iv.$hmac.$ciphertext_raw;
    }
    function decrypt ($encrypted_string, $encryption_key) {
        $cipher     = 'AES-256-CBC';
        $options    = OPENSSL_RAW_DATA;
        $hash_algo  = 'sha256';
        $sha2len    = 32;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = substr($encrypted_string, 0, $ivlen);
        $hmac = substr($encrypted_string, $ivlen, $sha2len);
        $ciphertext_raw = substr($encrypted_string, $ivlen+$sha2len);
        $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $encryption_key, $options, $iv);
        $calcmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
        if(function_exists('hash_equals')) {
            if (hash_equals($hmac, $calcmac)) return $original_plaintext;
        } else {
            if ($this->hash_equals_custom($hmac, $calcmac)) return $original_plaintext;
        }
    }
    /**
     * (Optional)
     * hash_equals() function polyfilling.
     * PHP 5.6+ timing attack safe comparison
     */
    function hash_equals_custom($knownString, $userString) {
        if (function_exists('mb_strlen')) {
            $kLen = mb_strlen($knownString, '8bit');
            $uLen = mb_strlen($userString, '8bit');
        } else {
            $kLen = strlen($knownString);
            $uLen = strlen($userString);
        }
        if ($kLen !== $uLen) {
            return false;
        }
        $result = 0;
        for ($i = 0; $i < $kLen; $i++) {
            $result |= (ord($knownString[$i]) ^ ord($userString[$i]));
        }
        return 0 === $result;
    }
}

define('ENCRYPTION_KEY', '__^%&Q@$&*!@#$%^&*^__');
$string = "This is the original string!";

$OpensslEncryption = new Openssl_EncryptDecrypt;
$encrypted = $OpensslEncryption->encrypt($string, ENCRYPTION_KEY);
$decrypted = $OpensslEncryption->decrypt($encrypted, ENCRYPTION_KEY);

在PHP中,可以使用一种名为OpenSSL的加密扩展函数对字符串进行加密和解密。

openssl_encrypt()函数:openssl_encrypt()函数用于加密数据。

语法如下:

openssl_encrypt(字符串$data,字符串$method,字符串$key, $options = 0,字符串$iv,字符串$tag= NULL,字符串$aad, int $tag_length = 16)

参数说明如下:

$data:存放需要加密的字符串或数据。

$method:使用openssl_get_cipher_methods()函数使用cipher方法。

$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()用于解密数据。

语法如下:

openssl_decrypt(字符串$data,字符串$method,字符串$key, int $options = 0,字符串$iv,字符串$tag,字符串$aad)

参数说明如下:

$data:存放需要加密的字符串或数据。

$method:使用openssl_get_cipher_methods()函数使用cipher方法。

$key:保存加密密钥。

$options:它保存OPENSSL_RAW_DATA和OPENSSL_ZERO_PADDING标志的位分离。

$iv:它保存的初始化向量不是NULL。

$tag:它保存使用AEAD密码模式(GCM或CCM)的身份验证标记。当身份验证失败时,openssl_decryption()返回FALSE。

$aad:它保存额外的身份验证数据。

返回值:成功时返回解密字符串,失败时返回FALSE。

方法:首先声明一个字符串并将其存储到变量中,然后使用openssl_encrypt()函数对给定的字符串进行加密,使用openssl_decrypt()函数对给定的字符串进行解密。

您可以在https://www.geeksforgeeks.org/how-to-encrypt-and-decrypt-a-php-string/上找到示例