你如何加密和解密PHP字符串?

夏期劇*_*期劇場 211 php security encryption cryptography encryption-symmetric

我的意思是:

Original String + Salt or Key --> Encrypted String
Encrypted String + Salt or Key --> Decrypted (Original String)
Run Code Online (Sandbox Code Playgroud)

也许是这样的:

"hello world!" + "ABCD1234" --> Encrypt --> "2a2ffa8f13220befbe30819047e23b2c" (may be, for e.g)
"2a2ffa8f13220befbe30819047e23b2c" --> Decrypt with "ABCD1234" --> "hello world!"
Run Code Online (Sandbox Code Playgroud)
  • 在PHP中,你怎么能这样做?

尝试使用Crypt_Blowfish,但它对我不起作用.

Sco*_*ski 381

在进一步做之前,请了解加密身份验证之间的区别,以及为什么您可能需要经过身份验证的加密而不仅仅是加密.

要实现经过身份验证的加密,您需要加密然后MAC.加密和身份验证的顺序非常重要!这个问题的现有答案之一就是犯了这个错误; 就像许多用PHP编写的加密库一样.

您应该避免实现自己的加密,而是使用由加密专家编写和审阅的安全库.

更新:PHP 7.2现在提供libsodium!为了获得最佳安全性,请将系统更新为使用PHP 7.2或更高版本,并且只遵循本答案中的libsodium建议.

如果您有PECL访问权限,请使用libsodium(如果您想要没有PECL的libsodium,请使用sodium_compat); 否则......
使用defuse/php-encryption ; 不要滚动你自己的加密!

上面链接的两个库使得在您自己的库中实现经过身份验证的加密变得轻松而轻松.

如果您仍然希望编写和部署自己的加密库,而不是互联网上每个加密专家的传统智慧,那么这些步骤就是您必须采取的步骤.

加密:

  1. 在CTR模式下使用AES进行加密.您也可以使用GCM(不需要单独的MAC).此外,ChaCha20和Salsa20(由libsodium提供)是流密码,不需要特殊模式.
  2. 除非您选择上面的GCM,否则您应该使用HMAC-SHA-256验证密文(或者,对于流密码,Poly1305 - 大多数libsodium API都会为您执行此操作).MAC应该涵盖IV和密文!

解密:

  1. 除非使用Poly1305或GCM,否则重新计算密文的MAC并将其与使用的MAC进行比较hash_equals().如果失败,则中止.
  2. 解密消息.

其他设计考虑因素:

  1. 不要压缩任何东西.密文不可压缩; 在加密之前压缩明文会导致信息泄露(例如,TL​​S上的CRIME和BREACH).
  2. 确保使用mb_strlen()mb_substr()使用'8bit'字符集模式来防止出现mbstring.func_overload问题.
  3. IV应该使用CSPRNG生成; 如果您正在使用mcrypt_create_iv(),请勿使用MCRYPT_RAND!
  4. 除非你使用AEAD结构,否则总是加密MAC!
  5. bin2hex(),base64_encode()等可能泄露关于通过缓存时间的加密密钥的信息.尽可能避免使用它们.

即使你遵循这里给出的建议,密码学也会出现很多问题.始终有一位加密专家审核您的实施.如果您没有幸运能够与当地大学的密码学学生成为私人朋友,您可以随时尝试使用Cryptography Stack Exchange论坛获取建议.

如果您需要对您的实施进行专业分析,您可以随时聘请一个声誉良好的安全顾问团队来审核您的PHP加密代码(披露:我的雇主).

重要提示:何时不使用加密

不要加密密码.您希望使用以下密码散列算法之一来散列它们:

切勿使用通用散列函数(MD5,SHA256)进行密码存储.

不要加密URL参数.这是工作的错误工具.

Libsodium的PHP字符串加密示例

如果你使用PHP <7.2或者没有安装libsodium,你可以使用sodium_compat来实现相同的结果(尽管速度较慢).

<?php
declare(strict_types=1);

/**
 * Encrypt a message
 * 
 * @param string $message - message to encrypt
 * @param string $key - encryption key
 * @return string
 * @throws RangeException
 */
function safeEncrypt(string $message, string $key): string
{
    if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
        throw new RangeException('Key is not the correct size (must be 32 bytes).');
    }
    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

    $cipher = base64_encode(
        $nonce.
        sodium_crypto_secretbox(
            $message,
            $nonce,
            $key
        )
    );
    sodium_memzero($message);
    sodium_memzero($key);
    return $cipher;
}

/**
 * Decrypt a message
 * 
 * @param string $encrypted - message encrypted with safeEncrypt()
 * @param string $key - encryption key
 * @return string
 * @throws Exception
 */
function safeDecrypt(string $encrypted, string $key): string
{   
    $decoded = base64_decode($encrypted);
    $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
    $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');

    $plain = sodium_crypto_secretbox_open(
        $ciphertext,
        $nonce,
        $key
    );
    if (!is_string($plain)) {
        throw new Exception('Invalid MAC');
    }
    sodium_memzero($ciphertext);
    sodium_memzero($key);
    return $plain;
}
Run Code Online (Sandbox Code Playgroud)

然后测试一下:

<?php
// This refers to the previous code block.
require "safeCrypto.php"; 

// Do this once then store it somehow:
$key = random_bytes(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);
Run Code Online (Sandbox Code Playgroud)

Halite - Libsodium变得更容易

一个我一直在工作的项目是称为加密库岩盐,其目的是使libsodium更简单,更直观.

<?php
use \ParagonIE\Halite\KeyFactory;
use \ParagonIE\Halite\Symmetric\Crypto as SymmetricCrypto;

// Generate a new random symmetric-key encryption key. You're going to want to store this:
$key = new KeyFactory::generateEncryptionKey();
// To save your encryption key:
KeyFactory::save($key, '/path/to/secret.key');
// To load it again:
$loadedkey = KeyFactory::loadEncryptionKey('/path/to/secret.key');

$message = 'We are all living in a yellow submarine';
$ciphertext = SymmetricCrypto::encrypt($message, $key);
$plaintext = SymmetricCrypto::decrypt($ciphertext, $key);

var_dump($ciphertext);
var_dump($plaintext);
Run Code Online (Sandbox Code Playgroud)

所有底层加密都由libsodium处理.

使用defuse/php-encryption的示例

<?php
/**
 * This requires https://github.com/defuse/php-encryption
 * php composer.phar require defuse/php-encryption
 */

use Defuse\Crypto\Crypto;
use Defuse\Crypto\Key;

require "vendor/autoload.php";

// Do this once then store it somehow:
$key = Key::createNewRandomKey();

$message = 'We are all living in a yellow submarine';

$ciphertext = Crypto::encrypt($message, $key);
$plaintext = Crypto::decrypt($ciphertext, $key);

var_dump($ciphertext);
var_dump($plaintext);
Run Code Online (Sandbox Code Playgroud)

注意:Crypto::encrypt()返回十六进制编码的输出.

加密密钥管理

如果您想使用"密码",请立即停止.您需要一个随机的128位加密密钥,而不是一个人类难忘的密码.

您可以存储加密密钥以供长期使用,如下所示:

$storeMe = bin2hex($key);
Run Code Online (Sandbox Code Playgroud)

并且,根据需要,您可以像这样检索它:

$key = hex2bin($storeMe);
Run Code Online (Sandbox Code Playgroud)

强烈建议只存储一个随机生成的密钥,以便长期使用而不是任何类型的密码作为密钥(或导出密钥).

如果您正在使用Defuse的库:

"但我真的想用密码."

这是一个坏主意,但没关系,这是如何安全地做到这一点.

首先,生成一个随机密钥并将其存储在常量中.

/**
 * Replace this with your own salt! 
 * Use bin2hex() then add \x before every 2 hex characters, like so:
 */
define('MY_PBKDF2_SALT', "\x2d\xb7\x68\x1a\x28\x15\xbe\x06\x33\xa0\x7e\x0e\x8f\x79\xd5\xdf");
Run Code Online (Sandbox Code Playgroud)

请注意,您正在添加额外的工作,并且可以使用此常量作为键,并为您节省很多心痛!

然后使用PBKDF2(如此)从您的密码中导出合适的加密密钥,而不是直接使用您的密码加密.

/**
 * Get an AES key from a static password and a secret salt
 * 
 * @param string $password Your weak password here
 * @param int $keysize Number of bytes in encryption key
 */
function getKeyFromPassword($password, $keysize = 16)
{
    return hash_pbkdf2(
        'sha256',
        $password,
        MY_PBKDF2_SALT,
        100000, // Number of iterations
        $keysize,
        true
    );
}
Run Code Online (Sandbox Code Playgroud)

不要只使用16个字符的密码.您的加密密钥将被巧妙地破坏.

  • [不加密密码](https://paragonie.com/blog/2015/08/you-wouldnt-base64-a-password-cryptography-decoded),用`password_hash()`哈希它们并用`检查它们` password_verify()`. (3认同)
  • "不要压缩任何东西." 你的意思是像HTTP,spdy和其他协议吗?在TLS之前?绝对主义的建议多少? (2认同)
  • Thx,我只需修改一行就可以使你的钠示例工作:`function getKeyFromPassword($ password,$ keysize =\Sodium\CRYPTO_SECRETBOX_KEYBYTES)` (2认同)
  • 哇!+1 提到不加密 URL 参数。我真的很喜欢你提供的文章:https://paragonie.com/blog/2015/09/comprehensive-guide-url-parameter-encryption-in-php (2认同)

Emi*_*oni 56

我迟到了,但是找到了正确的方法,我遇到了这个页面,它是谷歌搜索的最高回报之一,所以我想分享一下我对这个问题的看法,我认为这个问题是撰写本文时(2017年初)的最新信息.从PHP 7.1.0的mcrypt_decryptmcrypt_encrypt将要被弃用,因此,建立面向未来的代码应该使用openssl_encryptopenssl_decrypt

你可以这样做:

$string_to_encrypt="Test";
$password="password";
$encrypted_string=openssl_encrypt($string_to_encrypt,"AES-128-ECB",$password);
$decrypted_string=openssl_decrypt($encrypted_string,"AES-128-ECB",$password);
Run Code Online (Sandbox Code Playgroud)

重要说明:这使用ECB模式,这是不安全的.如果您想要一个简单的解决方案而不参加加密工程中的速成课程,请不要自己编写,只需使用库.

您也可以使用任何其他削片机方法,具体取决于您的安全需求.要了解可用的削片机方法,请参阅openssl_get_cipher_methods函数.

  • 谢谢,我很惊讶这个简单而明确的答案不会更受欢迎.当我想要的只是加密/解密一个简单的字符串时,我宁愿不阅读关于这个主题的10页讨论,如最佳答案. (7认同)
  • 这完全取决于用例!在某些情况下,这是非常好的。例如,我想在页面之间传递GET参数,比如说`prod_id = 123`,但是我只是不想让每个人都可以读取123,但是即使他们可以阅读,也不会有问题。能够将123替换为自定义值的攻击者不会造成任何伤害,他/她将只能获取任何其他产品的详细信息,但Joe Average User不会提供有关如何获取有关详细信息的线索。例如产品124。对于这样的情况,这是一个完美的解决方案,对于安全性而言,这是不可行的! (5认同)
  • 这不是一个安全的答案。[ECB模式](https://blog.filippo.io/the-ecb-penguin/)不应使用。如果您想要一个“简单明了的答案”,只需[使用库](https://github.com/defuse/php-encryption)。 (2认同)
  • @ScottArciszewski,是的,我承认我在寻找一些简单的代码时说得太快了。从那以后,我在自己的代码中添加了一个 IV 并使用了 CBC,这对我来说已经足够了。 (2认同)
  • “例如,我想在页面之间传递 GET 参数,假设 prod_id=123,但我只是不想让 123 对每个人都可读,但是即使他们可以读取它,也不会成为问题。” - 我可以建议一个更好的方法吗?https://paragonie.com/blog/2015/09/compressive-guide-url-parameter-encryption-in-php (2认同)

夏期劇*_*期劇場 43

什么不该做

警告:
此答案使用ECB.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;
}
?>
Run Code Online (Sandbox Code Playgroud)

  • **警告:这是不安全的**.ECB模式不应该用于字符串,ECB不采用IV,这是未经过身份验证的,它使用旧密码(Blowfish)代替AES,密钥不是二进制等等.**SO社区应该真的停止upvoting加密/解密只是"工作"**并开始提供已知安全的答案.如果您不确定,请不要投票. (81认同)
  • Ramesh,这是因为你得到了原始的加密数据.您可以使用base64获得更好的加密数据版本,如下所示:`base64_encode(encrypt($ string))` - 解密它:`decrypt(base64_decode($ encrypted))` (10认同)
  • 您可以使用"MCRYPT_MODE_CBC"而不是"MCRYPT_MODE_ECB"来确保更高的安全性. (8认同)
  • 正确的答案是使用[defuse/php-encryption](https://github.com/defuse/php-encryption)之类的东西,而不是编写自己的mcrypt代码. (4认同)
  • 我已经通过替换`mcrypt_encrypt`的示例代码来实现这一点:http://php.net/manual/en/function.mcrypt-encrypt.php.请注意,现在查看它可能应该在结尾处有一个字符"\ 0"的`rtrim`. (3认同)

夏期劇*_*期劇場 17

更新

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);
Run Code Online (Sandbox Code Playgroud)

  • 您如何创建加密密钥以及将其保存在哪里? (3认同)

Som*_*luk 16

对于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);
Run Code Online (Sandbox Code Playgroud)

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

  • 当然,它可能很容易使用。但它安全吗?它如何解决http://stackoverflow.com/a/30159120/781723中的问题?它使用经过身份验证的加密吗?它是否避免了侧通道漏洞并确保恒定时间的相等检查?它使用真正的随机密钥而不是密码/密码短语吗?它是否使用合适的操作模式?它是否正确生成随机 IV? (2认同)

Mar*_*cas 11

这些是使用AES256 CBC通过 PHP 加密/解密字符串的紧凑方法:

function encryptString($plaintext, $password, $encoding = null) {
    $iv = openssl_random_pseudo_bytes(16);
    $ciphertext = openssl_encrypt($plaintext, "AES-256-CBC", hash('sha256', $password, true), OPENSSL_RAW_DATA, $iv);
    $hmac = hash_hmac('sha256', $ciphertext.$iv, hash('sha256', $password, true), true);
    return $encoding == "hex" ? bin2hex($iv.$hmac.$ciphertext) : ($encoding == "base64" ? base64_encode($iv.$hmac.$ciphertext) : $iv.$hmac.$ciphertext);
}

function decryptString($ciphertext, $password, $encoding = null) {
    $ciphertext = $encoding == "hex" ? hex2bin($ciphertext) : ($encoding == "base64" ? base64_decode($ciphertext) : $ciphertext);
    if (!hash_equals(hash_hmac('sha256', substr($ciphertext, 48).substr($ciphertext, 0, 16), hash('sha256', $password, true), true), substr($ciphertext, 16, 32))) return null;
    return openssl_decrypt(substr($ciphertext, 48), "AES-256-CBC", hash('sha256', $password, true), OPENSSL_RAW_DATA, substr($ciphertext, 0, 16));
}
Run Code Online (Sandbox Code Playgroud)

用法:

$enc = encryptString("mysecretText", "myPassword");
$dec = decryptString($enc, "myPassword");
Run Code Online (Sandbox Code Playgroud)

编辑:这是新版本的函数,使用AES256 GCMPBKDF2作为密钥派生,更安全。

function str_encryptaesgcm($plaintext, $password, $encoding = null) {
    if ($plaintext != null && $password != null) {
        $keysalt = openssl_random_pseudo_bytes(16);
        $key = hash_pbkdf2("sha512", $password, $keysalt, 20000, 32, true);
        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("aes-256-gcm"));
        $tag = "";
        $encryptedstring = openssl_encrypt($plaintext, "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag, "", 16);
        return $encoding == "hex" ? bin2hex($keysalt.$iv.$encryptedstring.$tag) : ($encoding == "base64" ? base64_encode($keysalt.$iv.$encryptedstring.$tag) : $keysalt.$iv.$encryptedstring.$tag);
    }
}

function str_decryptaesgcm($encryptedstring, $password, $encoding = null) {
    if ($encryptedstring != null && $password != null) {
        $encryptedstring = $encoding == "hex" ? hex2bin($encryptedstring) : ($encoding == "base64" ? base64_decode($encryptedstring) : $encryptedstring);
        $keysalt = substr($encryptedstring, 0, 16);
        $key = hash_pbkdf2("sha512", $password, $keysalt, 20000, 32, true);
        $ivlength = openssl_cipher_iv_length("aes-256-gcm");
        $iv = substr($encryptedstring, 16, $ivlength);
        $tag = substr($encryptedstring, -16);
        return openssl_decrypt(substr($encryptedstring, 16 + $ivlength, -16), "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

$enc = str_encryptaesgcm("mysecretText", "myPassword", "base64"); // return a base64 encrypted string, you can also choose hex or null as encoding.
$dec = str_decryptaesgcm($enc, "myPassword", "base64");
Run Code Online (Sandbox Code Playgroud)


Bri*_*anH 7

历史记录:这是在PHP4时编写的.这就是我们现在所说的"遗留代码".

我把这个答案留给了历史目的 - 但现在有些方法已被弃用,DES加密方法不是推荐的做法,等等.

我没有更新此代码有两个原因:1)我不再使用PHP手工加密方法,2)此代码仍然用于其目的:展示加密如何工作的最小,简单概念用PHP.

如果您发现类似的简单,"PHP加密傻瓜"类型的源代码可以让人们开始使用10到20行或更少的代码,请在评论中告诉我.

除此之外,请享受早期PHP4简约加密答案的经典剧集.


理想情况下,您可以 - 或者可以获得 - 访问mcrypt PHP库,因为它肯定很受欢迎且非常有用.以下是不同种类的加密和一些示例代码: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 ); 
?> 
Run Code Online (Sandbox Code Playgroud)

一些警告:

1)当单向散列执行时,切勿使用可逆或"对称"加密.

2)如果数据真正敏感,如信用卡或社会安全号码,请停止; 你需要的不仅仅是任何简单的代码块,而是需要一个专为此目的而设计的加密库,并且需要大量的时间来研究必要的方法.此外,软件加密可能是敏感数据安全性的10%.这就像重新布线核电站 - 接受任务是危险和困难的,并且如果是这样的话,超出了你的知识范围.经济处罚可能是巨大的,因此最好使用服务并将责任运送给他们.

3)如此处所列,任何类型的易于实施的加密都可以合理地保护您想要避免的轻微重要信息,以防止在意外/故意泄漏的情况下窥探或限制暴露.但是看看密钥是如何以纯文本形式存储在Web服务器上的,如果他们可以获取数据,他们就可以获得解密密钥.

尽管如此,玩得开心:)

  • Eww,DES.哪个是AES? (9认同)
  • 自PHP 5.5.0起,mcrypt_ecb已被弃用依赖此功能是非常不鼓励的.http://php.net/manual/en/function.mcrypt-ecb.php (8认同)
  • @夏期剧场加密的结果是二进制数据.如果您需要它是人类可读的,请在其上使用base64或十六进制编码."我不能改变键值的长度吗?" 不同的对称加密算法对密钥值有不同的要求.'和输出的长度......'加密文本的长度必须至少与原始文本一样长,否则没有足够的信息来重新创建原始文本.(这是Pigeonhole原则的应用.)顺便说一句,你应该使用AES而不是DES.DES很容易破碎,不再安全. (3认同)
  • 谢谢!但有些问题.我将`M f= _=`奇怪的字符作为加密字符.我不能得到简单的人物?喜欢:`2a2ffa8f13220befbe30819047e23b2c`.另外,我不能改变`$ key_value`(固定为8 ???)的LENGTH和输出`$ encrypted_text`的LENGTH?(它不能是32或64长或更长?) (2认同)

Asc*_*con 5

如果您不想使用库(应该使用),则可以使用如下所示的东西(PHP 7):

function sign($message, $key) {
    return hash_hmac('sha256', $message, $key) . $message;
}

function verify($bundle, $key) {
    return hash_equals(
      hash_hmac('sha256', mb_substr($bundle, 64, null, '8bit'), $key),
      mb_substr($bundle, 0, 64, '8bit')
    );
}

function getKey($password, $keysize = 16) {
    return hash_pbkdf2('sha256',$password,'some_token',100000,$keysize,true);
}

function encrypt($message, $password) {
    $iv = random_bytes(16);
    $key = getKey($password);
    $result = sign(openssl_encrypt($message,'aes-256-ctr',$key,OPENSSL_RAW_DATA,$iv), $key);
    return bin2hex($iv).bin2hex($result);
}

function decrypt($hash, $password) {
    $iv = hex2bin(substr($hash, 0, 32));
    $data = hex2bin(substr($hash, 32));
    $key = getKey($password);
    if (!verify($data, $key)) {
      return null;
    }
    return openssl_decrypt(mb_substr($data, 64, null, '8bit'),'aes-256-ctr',$key,OPENSSL_RAW_DATA,$iv);
}

$string_to_encrypt='John Smith';
$password='password';
$encrypted_string=encrypt($string_to_encrypt, $password);
$decrypted_string=decrypt($encrypted_string, $password);
Run Code Online (Sandbox Code Playgroud)

  • 在您的情况下,可能应该这样做:`define(“ ENCRYPTION_KEY”,“ 123456 *”); $ string =“这是原始数据字符串!”; $ encrypted = openssl_encrypt($ string,'BF-ECB',ENCRYPTION_KEY); $ decrypted = openssl_decrypt($ encrypted,'BF-ECB',ENCRYPTION_KEY);` (2认同)