使用 PHP 最简单的双向加密

发布于 2025-01-04 21:14:48 字数 165 浏览 1 评论 0原文

在常见 PHP 安装中进行双向加密的最简单方法是什么?

我需要能够使用字符串密钥加密数据,并使用相同的密钥在另一端解密。

安全性并不像代码的可移植性那么重要,因此我希望能够使事情尽可能简单。目前,我正在使用 RC4 实现,但如果我能找到本机支持的东西,我想我可以节省很多不必要的代码。

What is the simplest way of doing two way encryption in common PHP installs?

I need to be able to encrypt data with a string key, and use the same key to decrypt on the other end.

The security isn't as big of a concern as the portability of the code, so I'd like to be able to keep things as simple as possible. Currently, I am using an RC4 implementation, but if I can find something natively supported I figure I can save a lot of unnecessary code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

演出会有结束 2025-01-11 21:14:48

重要:除非您有非常特定的用例,不加密密码,而是使用密码哈希算法。当有人说他们在服务器端应用程序中加密他们的密码时,他们要么不知情,要么正在描述危险的系统设计。 安全存储密码是一个完全独立的问题加密。

获悉情况。设计安全系统。

PHP 中的便携式数据加密

如果您使用 PHP 5.4 或更高版本 并且不想编写加密技术如果您自己模块,我建议使用提供经过身份验证的加密的现有库。我链接的库仅依赖于 PHP 提供的内容,并且由少数安全研究人员定期审查。 (包括我自己。)

如果您的可移植性目标不妨碍需要 PECL 扩展,libsodium< /strong> 比您或我可以用 PHP 编写的任何内容都强烈推荐。

更新 (2016-06-12): 您现在可以使用 sodium_compat 并使用无需安装 PECL 扩展即可提供相同的 crypto libsodium。

如果您想尝试密码学工程,请继续阅读。


首先,您应该花时间了解危险未经身份验证的加密密码毁灭原理

  • 加密数据仍然可能被恶意用户篡改。
  • 验证加密数据可防止篡改。
  • 验证未加密的数据并不能防止篡改。

加密和解密

PHP 中的加密实际上很简单(我们将使用 openssl_encrypt()openssl_decrypt() 一旦你做出了一些决定要加密您的信息,请参阅 openssl_get_cipher_methods() 以获取您的系统支持的方法列表。最好的选择是 CTR 模式下的 AES

  • aes-128-ctr
  • aes-192-ctr
  • aes-256-ctr

目前没有理由相信AES 密钥大小是一个需要担心的重要问题(由于 256- 中的密钥调度不良,可能并不是越大越好)位模式)。

注意:我们没有使用mcrypt,因为它是废弃软件 并且存在可能影响安全的未修补的错误。由于这些原因,我鼓励其他 PHP 开发人员也避免使用它。

使用 OpenSSL 的简单加密/解密包装器使用

class UnsafeCrypto
{
    const METHOD = 'aes-256-ctr';
    
    /**
     * Encrypts (but does not authenticate) a message
     * 
     * @param string $message - plaintext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encode - set to TRUE to return a base64-encoded 
     * @return string (raw binary)
     */
    public static function encrypt($message, $key, $encode = false)
    {
        $nonceSize = openssl_cipher_iv_length(self::METHOD);
        $nonce = openssl_random_pseudo_bytes($nonceSize);
        
        $ciphertext = openssl_encrypt(
            $message,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $nonce
        );
        
        // Now let's pack the IV and the ciphertext together
        // Naively, we can just concatenate
        if ($encode) {
            return base64_encode($nonce.$ciphertext);
        }
        return $nonce.$ciphertext;
    }
    
    /**
     * Decrypts (but does not verify) a message
     * 
     * @param string $message - ciphertext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encoded - are we expecting an encoded string?
     * @return string
     */
    public static function decrypt($message, $key, $encoded = false)
    {
        if ($encoded) {
            $message = base64_decode($message, true);
            if ($message === false) {
                throw new Exception('Encryption failure');
            }
        }

        $nonceSize = openssl_cipher_iv_length(self::METHOD);
        $nonce = mb_substr($message, 0, $nonceSize, '8bit');
        $ciphertext = mb_substr($message, $nonceSize, null, '8bit');
        
        $plaintext = openssl_decrypt(
            $ciphertext,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $nonce
        );
        
        return $plaintext;
    }
}

示例

$message = 'Ready your ammunition; we attack at dawn.';
$key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encrypted = UnsafeCrypto::encrypt($message, $key);
$decrypted = UnsafeCrypto::decrypt($encrypted, $key);

var_dump($encrypted, $decrypted);

演示https://3v4l.org/jl7qR


上面的简单加密库使用起来仍然不安全。我们需要在解密之前验证密文并验证它们

注意:默认情况下,UnsafeCrypto::encrypt() 将返回原始二进制字符串。如果您需要以二进制安全格式(base64 编码)存储它,请这样调用:

$message = 'Ready your ammunition; we attack at dawn.';
$key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encrypted = UnsafeCrypto::encrypt($message, $key, true);
$decrypted = UnsafeCrypto::decrypt($encrypted, $key, true);

var_dump($encrypted, $decrypted);

演示http://3v4l.org/f5K93

简单身份验证包装器

class SaferCrypto extends UnsafeCrypto
{
    const HASH_ALGO = 'sha256';
    
    /**
     * Encrypts then MACs a message
     * 
     * @param string $message - plaintext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encode - set to TRUE to return a base64-encoded string
     * @return string (raw binary)
     */
    public static function encrypt($message, $key, $encode = false)
    {
        list($encKey, $authKey) = self::splitKeys($key);
        
        // Pass to UnsafeCrypto::encrypt
        $ciphertext = parent::encrypt($message, $encKey);
        
        // Calculate a MAC of the IV and ciphertext
        $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true);
        
        if ($encode) {
            return base64_encode($mac.$ciphertext);
        }
        // Prepend MAC to the ciphertext and return to caller
        return $mac.$ciphertext;
    }
    
    /**
     * Decrypts a message (after verifying integrity)
     * 
     * @param string $message - ciphertext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encoded - are we expecting an encoded string?
     * @return string (raw binary)
     */
    public static function decrypt($message, $key, $encoded = false)
    {
        list($encKey, $authKey) = self::splitKeys($key);
        if ($encoded) {
            $message = base64_decode($message, true);
            if ($message === false) {
                throw new Exception('Encryption failure');
            }
        }
        
        // Hash Size -- in case HASH_ALGO is changed
        $hs = mb_strlen(hash(self::HASH_ALGO, '', true), '8bit');
        $mac = mb_substr($message, 0, $hs, '8bit');
        
        $ciphertext = mb_substr($message, $hs, null, '8bit');
        
        $calculated = hash_hmac(
            self::HASH_ALGO,
            $ciphertext,
            $authKey,
            true
        );
        
        if (!self::hashEquals($mac, $calculated)) {
            throw new Exception('Encryption failure');
        }
        
        // Pass to UnsafeCrypto::decrypt
        $plaintext = parent::decrypt($ciphertext, $encKey);
        
        return $plaintext;
    }
    
    /**
     * Splits a key into two separate keys; one for encryption
     * and the other for authenticaiton
     * 
     * @param string $masterKey (raw binary)
     * @return array (two raw binary strings)
     */
    protected static function splitKeys($masterKey)
    {
        // You really want to implement HKDF here instead!
        return [
            hash_hmac(self::HASH_ALGO, 'ENCRYPTION', $masterKey, true),
            hash_hmac(self::HASH_ALGO, 'AUTHENTICATION', $masterKey, true)
        ];
    }
    
    /**
     * Compare two strings without leaking timing information
     * 
     * @param string $a
     * @param string $b
     * @ref https://paragonie.com/b/WS1DLx6BnpsdaVQW
     * @return boolean
     */
    protected static function hashEquals($a, $b)
    {
        if (function_exists('hash_equals')) {
            return hash_equals($a, $b);
        }
        $nonce = openssl_random_pseudo_bytes(32);
        return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce);
    }
}

使用示例

$message = 'Ready your ammunition; we attack at dawn.';
$key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encrypted = SaferCrypto::encrypt($message, $key);
$decrypted = SaferCrypto::decrypt($encrypted, $key);

var_dump($encrypted, $decrypted);

演示原始二进制文件base64 编码


如果有人希望使用此生产环境中的 SaferCrypto 库,或者您自己实现相同概念,我强烈建议您联系您的常驻密码学家以获取更多信息之前的第二意见 你做。他们会告诉你我可能没有意识到的错误。

使用 会更好一个有信誉的密码学库

Important: Unless you have a very particular use-case, do not encrypt passwords, use a password hashing algorithm instead. When someone says they encrypt their passwords in a server-side application, they're either uninformed or they're describing a dangerous system design. Safely storing passwords is a totally separate problem from encryption.

Be informed. Design safe systems.

Portable Data Encryption in PHP

If you're using PHP 5.4 or newer and don't want to write a cryptography module yourself, I recommend using an existing library that provides authenticated encryption. The library I linked relies only on what PHP provides and is under periodic review by a handful of security researchers. (Myself included.)

If your portability goals do not prevent requiring PECL extensions, libsodium is highly recommended over anything you or I can write in PHP.

Update (2016-06-12): You can now use sodium_compat and use the same crypto libsodium offers without installing PECL extensions.

If you want to try your hand at cryptography engineering, read on.


First, you should take the time to learn the dangers of unauthenticated encryption and the Cryptographic Doom Principle.

  • Encrypted data can still be tampered with by a malicious user.
  • Authenticating the encrypted data prevents tampering.
  • Authenticating the unencrypted data does not prevent tampering.

Encryption and Decryption

Encryption in PHP is actually simple (we're going to use openssl_encrypt() and openssl_decrypt() once you have made some decisions about how to encrypt your information. Consult openssl_get_cipher_methods() for a list of the methods supported on your system. The best choice is AES in CTR mode:

  • aes-128-ctr
  • aes-192-ctr
  • aes-256-ctr

There is currently no reason to believe that the AES key size is a significant issue to worry about (bigger is probably not better, due to bad key-scheduling in the 256-bit mode).

Note: We are not using mcrypt because it is abandonware and has unpatched bugs that might be security-affecting. Because of these reasons, I encourage other PHP developers to avoid it as well.

Simple Encryption/Decryption Wrapper using OpenSSL

class UnsafeCrypto
{
    const METHOD = 'aes-256-ctr';
    
    /**
     * Encrypts (but does not authenticate) a message
     * 
     * @param string $message - plaintext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encode - set to TRUE to return a base64-encoded 
     * @return string (raw binary)
     */
    public static function encrypt($message, $key, $encode = false)
    {
        $nonceSize = openssl_cipher_iv_length(self::METHOD);
        $nonce = openssl_random_pseudo_bytes($nonceSize);
        
        $ciphertext = openssl_encrypt(
            $message,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $nonce
        );
        
        // Now let's pack the IV and the ciphertext together
        // Naively, we can just concatenate
        if ($encode) {
            return base64_encode($nonce.$ciphertext);
        }
        return $nonce.$ciphertext;
    }
    
    /**
     * Decrypts (but does not verify) a message
     * 
     * @param string $message - ciphertext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encoded - are we expecting an encoded string?
     * @return string
     */
    public static function decrypt($message, $key, $encoded = false)
    {
        if ($encoded) {
            $message = base64_decode($message, true);
            if ($message === false) {
                throw new Exception('Encryption failure');
            }
        }

        $nonceSize = openssl_cipher_iv_length(self::METHOD);
        $nonce = mb_substr($message, 0, $nonceSize, '8bit');
        $ciphertext = mb_substr($message, $nonceSize, null, '8bit');
        
        $plaintext = openssl_decrypt(
            $ciphertext,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $nonce
        );
        
        return $plaintext;
    }
}

Usage Example

$message = 'Ready your ammunition; we attack at dawn.';
$key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encrypted = UnsafeCrypto::encrypt($message, $key);
$decrypted = UnsafeCrypto::decrypt($encrypted, $key);

var_dump($encrypted, $decrypted);

Demo: https://3v4l.org/jl7qR


The above simple crypto library still is not safe to use. We need to authenticate ciphertexts and verify them before we decrypt.

Note: By default, UnsafeCrypto::encrypt() will return a raw binary string. Call it like this if you need to store it in a binary-safe format (base64-encoded):

$message = 'Ready your ammunition; we attack at dawn.';
$key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encrypted = UnsafeCrypto::encrypt($message, $key, true);
$decrypted = UnsafeCrypto::decrypt($encrypted, $key, true);

var_dump($encrypted, $decrypted);

Demo: http://3v4l.org/f5K93

Simple Authentication Wrapper

class SaferCrypto extends UnsafeCrypto
{
    const HASH_ALGO = 'sha256';
    
    /**
     * Encrypts then MACs a message
     * 
     * @param string $message - plaintext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encode - set to TRUE to return a base64-encoded string
     * @return string (raw binary)
     */
    public static function encrypt($message, $key, $encode = false)
    {
        list($encKey, $authKey) = self::splitKeys($key);
        
        // Pass to UnsafeCrypto::encrypt
        $ciphertext = parent::encrypt($message, $encKey);
        
        // Calculate a MAC of the IV and ciphertext
        $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true);
        
        if ($encode) {
            return base64_encode($mac.$ciphertext);
        }
        // Prepend MAC to the ciphertext and return to caller
        return $mac.$ciphertext;
    }
    
    /**
     * Decrypts a message (after verifying integrity)
     * 
     * @param string $message - ciphertext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encoded - are we expecting an encoded string?
     * @return string (raw binary)
     */
    public static function decrypt($message, $key, $encoded = false)
    {
        list($encKey, $authKey) = self::splitKeys($key);
        if ($encoded) {
            $message = base64_decode($message, true);
            if ($message === false) {
                throw new Exception('Encryption failure');
            }
        }
        
        // Hash Size -- in case HASH_ALGO is changed
        $hs = mb_strlen(hash(self::HASH_ALGO, '', true), '8bit');
        $mac = mb_substr($message, 0, $hs, '8bit');
        
        $ciphertext = mb_substr($message, $hs, null, '8bit');
        
        $calculated = hash_hmac(
            self::HASH_ALGO,
            $ciphertext,
            $authKey,
            true
        );
        
        if (!self::hashEquals($mac, $calculated)) {
            throw new Exception('Encryption failure');
        }
        
        // Pass to UnsafeCrypto::decrypt
        $plaintext = parent::decrypt($ciphertext, $encKey);
        
        return $plaintext;
    }
    
    /**
     * Splits a key into two separate keys; one for encryption
     * and the other for authenticaiton
     * 
     * @param string $masterKey (raw binary)
     * @return array (two raw binary strings)
     */
    protected static function splitKeys($masterKey)
    {
        // You really want to implement HKDF here instead!
        return [
            hash_hmac(self::HASH_ALGO, 'ENCRYPTION', $masterKey, true),
            hash_hmac(self::HASH_ALGO, 'AUTHENTICATION', $masterKey, true)
        ];
    }
    
    /**
     * Compare two strings without leaking timing information
     * 
     * @param string $a
     * @param string $b
     * @ref https://paragonie.com/b/WS1DLx6BnpsdaVQW
     * @return boolean
     */
    protected static function hashEquals($a, $b)
    {
        if (function_exists('hash_equals')) {
            return hash_equals($a, $b);
        }
        $nonce = openssl_random_pseudo_bytes(32);
        return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce);
    }
}

Usage Example

$message = 'Ready your ammunition; we attack at dawn.';
$key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encrypted = SaferCrypto::encrypt($message, $key);
$decrypted = SaferCrypto::decrypt($encrypted, $key);

var_dump($encrypted, $decrypted);

Demos: raw binary, base64-encoded


If anyone wishes to use this SaferCrypto library in a production environment, or your own implementation of the same concepts, I strongly recommend reaching out to your resident cryptographers for a second opinion before you do. They'll be able tell you about mistakes that I might not even be aware of.

You will be much better off using a reputable cryptography library.

一直在等你来 2025-01-11 21:14:48

已编辑:

您确实应该使用 openssl_encrypt() & openssl_decrypt()

作为斯科特 说,Mcrypt 不是一个好主意,因为它自 2007 年以来就没有更新过。

甚至有一个 RFC 从 PHP 中删除 Mcrypt - https://wiki.php.net/rfc/mcrypt-viking-funeral

Edited:

You should really be using openssl_encrypt() & openssl_decrypt()

As Scott says, Mcrypt is not a good idea as it has not been updated since 2007.

There is even an RFC to remove Mcrypt from PHP - https://wiki.php.net/rfc/mcrypt-viking-funeral

桃气十足 2025-01-11 21:14:48

使用 mcrypt_encrypt()mcrypt_decrypt() 以及相应的参数。非常简单直接,而且您使用经过实战检验的加密包。

编辑

在此回答后 5 年零 4 个月,mcrypt 扩展现在正在弃用并最终从 PHP 中删除。

Use mcrypt_encrypt() and mcrypt_decrypt() with corresponding parameters. Really easy and straight forward, and you use a battle-tested encryption package.

EDIT

5 years and 4 months after this answer, the mcrypt extension is now in the process of deprecation and eventual removal from PHP.

向日葵 2025-01-11 21:14:48

使用 openssl_encrypt() 进行加密
openssl_encrypt 函数提供了一种安全且简单的方法来加密数据。

在下面的脚本中,我们使用 AES128 加密方法,但您可以根据您要加密的内容考虑其他类型的加密方法。

<?php
$message_to_encrypt = "Yoroshikune";
$secret_key = "my-secret-key";
$method = "aes128";
$iv_length = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($iv_length);

$encrypted_message = openssl_encrypt($message_to_encrypt, $method, $secret_key, 0, $iv);

echo $encrypted_message;
?>

以下是所使用变量的解释:

message_to_encrypt :要加密的数据
Secret_key :这是您的加密“密码”。一定不要选择太简单的东西,并小心不要与其他人分享你的密钥
method :加密方法。这里我们选择AES128。
iv_length 和 iv :使用字节准备加密
crypto_message :包含加密消息的变量

使用 openssl_decrypt() 解密
现在您已加密数据,您可能需要解密它才能重新使用您首先包含在变量中的消息。为此,我们将使用函数 openssl_decrypt()。

<?php
$message_to_encrypt = "Yoroshikune";
$secret_key = "my-secret-key";
$method = "aes128";
$iv_length = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($iv_length);
$encrypted_message = openssl_encrypt($message_to_encrypt, $method, $secret_key, 0, $iv);

$decrypted_message = openssl_decrypt($encrypted_message, $method, $secret_key, 0, $iv);

echo $decrypted_message;
?>

openssl_decrypt() 提出的解密方法与 openssl_encrypt() 接近。

唯一的区别是,您需要添加已加密的消息作为 openssl_decrypt() 的第一个参数,而不是添加 $message_to_encrypt。

注意:需要保存密钥和 iv 才能解密。

Encrypting using openssl_encrypt()
The openssl_encrypt function provides a secured and easy way to encrypt your data.

In the script below, we use the AES128 encryption method, but you may consider other kind of encryption method depending on what you want to encrypt.

<?php
$message_to_encrypt = "Yoroshikune";
$secret_key = "my-secret-key";
$method = "aes128";
$iv_length = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($iv_length);

$encrypted_message = openssl_encrypt($message_to_encrypt, $method, $secret_key, 0, $iv);

echo $encrypted_message;
?>

Here is an explanation of the variables used :

message_to_encrypt : the data you want to encrypt
secret_key : it is your ‘password’ for encryption. Be sure not to choose something too easy and be careful not to share your secret key with other people
method : the method of encryption. Here we chose AES128.
iv_length and iv : prepare the encryption using bytes
encrypted_message : the variable including your encrypted message

Decrypting using openssl_decrypt()
Now you encrypted your data, you may need to decrypt it in order to re-use the message you first included into a variable. In order to do so, we will use the function openssl_decrypt().

<?php
$message_to_encrypt = "Yoroshikune";
$secret_key = "my-secret-key";
$method = "aes128";
$iv_length = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($iv_length);
$encrypted_message = openssl_encrypt($message_to_encrypt, $method, $secret_key, 0, $iv);

$decrypted_message = openssl_decrypt($encrypted_message, $method, $secret_key, 0, $iv);

echo $decrypted_message;
?>

The decrypt method proposed by openssl_decrypt() is close to openssl_encrypt().

The only difference is that instead of adding $message_to_encrypt, you will need to add your already encrypted message as the first argument of openssl_decrypt().

Note: The secret key and iv needs to be saved in order to decrypt.

百变从容 2025-01-11 21:14:48

PHP 7.2 完全脱离了 Mcrypt,现在的加密基于可维护的 Libsodium 库。

您所有的加密需求都可以通过Libsodium库基本解决。

// On Alice's computer:
$msg = 'This comes from Alice.';
$signed_msg = sodium_crypto_sign($msg, $secret_sign_key);


// On Bob's computer:
$original_msg = sodium_crypto_sign_open($signed_msg, $alice_sign_publickey);
if ($original_msg === false) {
    throw new Exception('Invalid signature');
} else {
    echo $original_msg; // Displays "This comes from Alice."
}

Libsodium 文档:https://github.com/paragonie/pecl-libsodium-doc

PHP 7.2 moved completely away from Mcrypt and the encryption now is based on the maintainable Libsodium library.

All your encryption needs can be basically resolved through Libsodium library.

// On Alice's computer:
$msg = 'This comes from Alice.';
$signed_msg = sodium_crypto_sign($msg, $secret_sign_key);


// On Bob's computer:
$original_msg = sodium_crypto_sign_open($signed_msg, $alice_sign_publickey);
if ($original_msg === false) {
    throw new Exception('Invalid signature');
} else {
    echo $original_msg; // Displays "This comes from Alice."
}

Libsodium documentation: https://github.com/paragonie/pecl-libsodium-doc

浊酒尽余欢 2025-01-11 21:14:48

重要这个答案仅对 PHP 5 有效,在 PHP 7 中使用内置加密函数。

这是简单但足够安全的实现:

  • CBC 模式下的 AES-256 加密
  • PBKDF2,用于根据纯文本密码
  • HMAC 创建加密密钥来验证加密消息。

代码和示例位于:https://stackoverflow.com/a/19445173/1387163

IMPORTANT this answer is valid only for PHP 5, in PHP 7 use built-in cryptographic functions.

Here is simple but secure enough implementation:

  • AES-256 encryption in CBC mode
  • PBKDF2 to create encryption key out of plain-text password
  • HMAC to authenticate the encrypted message.

Code and examples are here: https://stackoverflow.com/a/19445173/1387163

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文