Hướng dẫn how we can encrypt any string using php? - làm thế nào chúng ta có thể mã hóa bất kỳ chuỗi nào bằng php?

Trước khi bạn làm bất cứ điều gì xa hơn, hãy tìm cách hiểu sự khác biệt giữa mã hóa và xác thực và tại sao bạn có thể muốn mã hóa được xác thực thay vì chỉ mã hóa.encryption and authentication, and why you probably want authenticated encryption rather than just encryption.

Để thực hiện mã hóa được xác thực, bạn muốn mã hóa sau đó Mac. Thứ tự mã hóa và xác thực là rất quan trọng! Một trong những câu trả lời hiện có cho câu hỏi này đã phạm sai lầm này; cũng như nhiều thư viện mật mã được viết bằng PHP.

Bạn nên tránh thực hiện mật mã của riêng mình, và thay vào đó sử dụng một thư viện an toàn được viết và xem xét bởi các chuyên gia mật mã.

Cập nhật: Php 7.2 Bây giờ cung cấp libsodium! Để bảo mật tốt nhất, hãy cập nhật các hệ thống của bạn để sử dụng Php 7.2 trở lên và chỉ làm theo lời khuyên của libsodium trong câu trả lời này.! For best security, update your systems to use PHP 7.2 or higher and only follow the libsodium advice in this answer.

Sử dụng libsodium nếu bạn có quyền truy cập PECL (hoặc natri_compat nếu bạn muốn libsodium mà không có PECL); Nếu không ... sử dụng Defuse/Php-Entction; Đừng cuộn mật mã của riêng bạn!
Use defuse/php-encryption; don't roll your own cryptography!

Cả hai thư viện được liên kết ở trên đều dễ dàng và không đau khi thực hiện mã hóa được xác thực vào các thư viện của riêng bạn.

Nếu bạn vẫn muốn viết và triển khai thư viện mật mã của riêng mình, chống lại sự khôn ngoan thông thường của mọi chuyên gia về mật mã trên internet, đây là những bước bạn sẽ phải thực hiện.

Encryption:

  1. Mã hóa bằng cách sử dụng AES ở chế độ CTR. Bạn cũng có thể sử dụng GCM (loại bỏ sự cần thiết của Mac riêng biệt). Ngoài ra, chacha20 và salsa20 (được cung cấp bởi libsodium) là các mật mã luồng và không cần các chế độ đặc biệt.
  2. Trừ khi bạn chọn GCM ở trên, bạn nên xác thực bản mã với HMAC-SHA-256 (hoặc, đối với các mật mã luồng, poly1305-hầu hết các API libsodium làm điều này cho bạn). Mac nên bao gồm IV cũng như bản mã!The MAC should cover the IV as well as the ciphertext!

Decryption:

  1. Trừ khi Poly1305 hoặc GCM được sử dụng, tính toán lại MAC của bản mã và so sánh nó với MAC được gửi bằng hash_equals(). Nếu nó thất bại, hủy bỏ.
  2. Giải mã tin nhắn.

Những cân nhắc thiết kế khác:

  1. Không nén bất cứ thứ gì bao giờ. Bản mã không thể nén; Nén bản rõ trước khi mã hóa có thể dẫn đến rò rỉ thông tin (ví dụ: tội phạm và vi phạm trên TLS).
  2. Đảm bảo bạn sử dụng mb_strlen()
    <?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);
    
    0, sử dụng chế độ bộ ký tự
    <?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);
    
    1 để ngăn chặn các vấn đề
    <?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);
    
    2.
  3. IV nên tạo bằng CSPRNG; Nếu bạn đang sử dụng
    <?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);
    
    3, không sử dụng
    <?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);
    
    4!DO NOT USE
    <?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);
    
    4
    !
    • Ngoài ra, hãy kiểm tra Random_Compat.
  4. Trừ khi bạn đang sử dụng cấu trúc AEAD, luôn luôn mã hóa thì Mac!ALWAYS encrypt then MAC!
  5. <?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);
    
    5,
    <?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);
    
    6, v.v. có thể rò rỉ thông tin về các khóa mã hóa của bạn thông qua thời gian bộ đệm. Tránh chúng nếu có thể.

Ngay cả khi bạn làm theo lời khuyên được đưa ra ở đây, rất nhiều điều có thể đi sai với mật mã. Luôn có một chuyên gia mật mã xem xét việc thực hiện của bạn. Nếu bạn không may mắn được làm bạn cá nhân với một sinh viên mật mã tại trường đại học địa phương của bạn, bạn luôn có thể thử Diễn đàn trao đổi ngăn xếp mật mã để được tư vấn.Always have a cryptography expert review your implementation. If you are not fortunate enough to be personal friends with a cryptography student at your local university, you can always try the Cryptography Stack Exchange forum for advice.

Nếu bạn cần một phân tích chuyên nghiệp về việc thực hiện của mình, bạn luôn có thể thuê một nhóm tư vấn bảo mật có uy tín để xem xét mã mật mã PHP của bạn (Tiết lộ: Chủ nhân của tôi).

Quan trọng: Khi nào không sử dụng mã hóa

Không mã hóa mật khẩu. Thay vào đó, bạn muốn băm chúng, sử dụng một trong các thuật toán lấy mật khẩu này:. You want to hash them instead, using one of these password-hashing algorithms:

  • Argon2
  • Scrypt
  • bcrypt
  • PBKDF2-SHA256 với 86.000 lần lặp

Không bao giờ sử dụng hàm băm mục đích chung (MD5, SHA256) để lưu trữ mật khẩu.

Không mã hóa các tham số URL. Đó là công cụ sai cho công việc. It's the wrong tool for the job.

Ví dụ mã hóa chuỗi PHP với libsodium

Nếu bạn đang sử dụng PHP <7.2 hoặc không được cài đặt libsodium, bạn có thể sử dụng natri_compat để hoàn thành kết quả tương tự (mặc dù chậm hơn).

<?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;
}

Sau đó để kiểm tra nó:

<?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);

Halite - libsodium làm cho dễ dàng hơn

Một trong những dự án tôi đã thực hiện là một thư viện mã hóa có tên Halite, nhằm mục đích làm cho libsodium dễ dàng hơn và trực quan hơn.

<?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);

Tất cả các mật mã cơ bản được xử lý bởi libsodium.

Ví dụ với độ lệch/Php-Repry

<?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);

Lưu ý:

<?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);
7 Trả về đầu ra được mã hóa hex.:
<?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);
7 returns hex-encoded output.

Quản lý khóa mã hóa

Nếu bạn muốn sử dụng "mật khẩu", hãy dừng ngay bây giờ. Bạn cần một khóa mã hóa 128 bit ngẫu nhiên, không phải là mật khẩu đáng nhớ của con người.

Bạn có thể lưu trữ khóa mã hóa để sử dụng lâu dài như vậy:

$storeMe = bin2hex($key);

Và, theo yêu cầu, bạn có thể lấy nó như vậy:

$key = hex2bin($storeMe);

Tôi thực sự khuyên bạn chỉ nên lưu trữ một khóa được tạo ngẫu nhiên để sử dụng lâu dài thay vì bất kỳ loại mật khẩu nào làm khóa (hoặc để lấy phím).strongly recommend just storing a randomly generated key for long-term use instead of any sort of password as the key (or to derive the key).

Nếu bạn đang sử dụng thư viện của Defuse:

  • <?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);
    
    8
  • <?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);
    
    9

"Nhưng tôi thực sự muốn sử dụng mật khẩu."

Đó là một ý tưởng tồi, nhưng không sao, đây là cách làm điều đó một cách an toàn.

Đầu tiên, tạo một khóa ngẫu nhiên và lưu trữ nó trong một hằng số.

/**
 * 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");

Lưu ý rằng bạn đang thêm công việc và chỉ có thể sử dụng hằng số này làm chìa khóa và tiết kiệm cho mình rất nhiều nỗi đau!

Sau đó, sử dụng PBKDF2 (như vậy) để lấy khóa mã hóa phù hợp từ mật khẩu của bạn thay vì mã hóa trực tiếp bằng mật khẩu của bạn.

/**
 * 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
    );
}

Đừng chỉ sử dụng mật khẩu 16 ký tự. Khóa mã hóa của bạn sẽ bị phá vỡ một cách hài hước.

Làm cách nào để mã hóa một chuỗi?

Steps:..
Nhập thư viện RSA ..
Tạo khóa công khai và riêng tư với RSA. ....
Mã hóa chuỗi thành chuỗi byte ..
Sau đó mã hóa chuỗi byte bằng khóa công khai ..
Sau đó chuỗi được mã hóa có thể được giải mã bằng khóa riêng ..
Khóa công khai chỉ có thể được sử dụng để mã hóa và riêng tư chỉ có thể được sử dụng để giải mã ..

Làm thế nào bạn có thể mã hóa mật khẩu bằng PHP?

Mã hóa mật khẩu: Để tạo hàm băm từ chuỗi, chúng tôi sử dụng hàm password_hash ().Hàm password_hash () tạo ra một hàm băm mật khẩu mới của chuỗi bằng một trong các thuật toán băm có sẵn.To generate a hash from the string, we use the password_hash() function. The password_hash() function creates a new password hash of the string using one of the available hashing algorithm.

Làm thế nào kiểm tra chuỗi được mã hóa hoặc không trong PHP?

Để kiểm tra xem nó được mã hóa, bạn cần khóa đã mã hóa giá trị.Nếu bạn không có khóa, bạn có thể thử kiểm tra một chữ ký ngôn ngữ nhất định (số lượng xảy ra trong chuỗi của một số ký tự nhất định).Loại mã hóa sẽ khá khó phát hiện.you need the key that has encrypted the value. If you don't have the key you could maybe try testing a certain language signature (the amount of occurences in the string of certain characters). The type of encryption would be rather difficult to detect.

Kỹ thuật mã hóa trong PHP là gì?

PHP bao gồm một thuật toán băm để mã hóa mật khẩu.Đối với hầu hết các phần, nó được sử dụng trong các chức năng để mã hóa mật khẩu là Crypt (), password_hash () và md5 ().crypt(), password_hash() and md5().