Tiện ích mở rộng Libsodium PHP

Thư viện tiền điện tử Natri (libsodium) là thư viện phần mềm hiện đại, dễ sử dụng để mã hóa, giải mã, chữ ký, băm mật khẩu, v.v. Nó là một nhánh rẽ của NaCl di động, có thể biên dịch chéo, có thể cài đặt, có thể đóng gói, với API tương thích và API mở rộng để cải thiện khả năng sử dụng hơn nữa

Mục tiêu của nó là cung cấp tất cả các hoạt động cốt lõi cần thiết để xây dựng các công cụ mật mã cấp cao hơn

Natri hỗ trợ nhiều trình biên dịch và hệ điều hành, bao gồm Windows (với MinGW hoặc Visual Studio, x86 và x64), iOS và Android

Để cài đặt tiện ích mở rộng này trên PHP 7. 1, hãy chạy các lệnh sau với tư cách là người dùng root của máy chủ của bạn

Xác minh phiên bản php và pecl

php -v
pecl version

Nếu bạn chưa cài đặt trình quản lý gói PECL trên hệ thống của mình, hãy đảm bảo rằng bạn làm điều đó trước. Có hướng dẫn cài đặt PECL có sẵn trên Internet cho hầu hết mọi hệ điều hành mà PHP hỗ trợ

Nếu php của bạn không phải là 7. 1 sau đó sử dụng lệnh /usr/bin/php7.1 thay vì lệnh php

Cài đặt phần mở rộng libsodium

PECL Libsodium đề cập đến tiện ích mở rộng PHP có sẵn dưới dạng gói PECL hiển thị API libsodium cho các nhà phát triển PHP

Phiên bản 7. 2. 0 và mới hơn của ngôn ngữ lập trình PHP bao gồm tiện ích mở rộng Natri (được gọi là ext/sodium) làm thư viện mật mã cốt lõi. Phiên bản 2 của phần mở rộng PHP trong PECL tương thích với ext/sodium trong PHP 7. 2

sudo pecl install -f libsodium

Trên một số bản phân phối Linux như Debian, bạn có thể phải cài đặt PECL (php-pear), gói phát triển PHP (php-dev) và trình biên dịch (build-essential) trước khi chạy lệnh này

Sau khi cài đặt libsodium máng pecl thành công, bạn nên thêm tiện ích mở rộng sodium.so vào php.ini

sudo echo "extension = sodium.so" > /etc/php/7.1/mods-available/sodium.ini
sudo phpenmod sodium 

Bạn có thể đạt được kết quả này bằng cách chạy

sudo pecl install -f libsodium
0 natri hoặc
sudo pecl install -f libsodium
1 natri, tùy thuộc vào máy chủ web bạn sử dụng. Đảm bảo bạn khởi động lại máy chủ web của mình sau khi cài đặt ext/sodium

Xác minh rằng tiện ích mở rộng đã được cài đặt

Sau khi cài đặt cả thư viện và tiện ích mở rộng PHP, hãy tạo một tập lệnh php thử nghiệm nhanh để xác minh rằng bạn đã cài đặt đúng phiên bản libsodium


var_dump([
    SODIUM_LIBRARY_MAJOR_VERSION,
    SODIUM_LIBRARY_MINOR_VERSION,
    SODIUM_LIBRARY_VERSION
]);

Hoặc bạn có thể xác minh qua thiết bị đầu cuối

php -i | grep "sodium"

Đầu ra sẽ trông như thế này

/etc/php/7.1/cli/conf.d/ext-libsodium.ini,
libsodium
libsodium support => enabled
libsodium compiled version => 2.0.10

Chúng tôi có thể sử dụng Libsodium trên PHP cũ hơn và/hoặc nếu chúng tôi không thể cài đặt phần mở rộng PHP không?

Bạn đang tìm kiếm sodium_compat, hỗ trợ PHP 5. 2 đến 7. 2, nhưng không hỗ trợ tất cả các tính năng của libsodium. Đặc biệt, nó không cung cấp thuật toán băm mật khẩu

Tài liệu đầy đủ tại đây. Sử dụng Libsodium trong Dự án PHP, hướng dẫn sử dụng tiện ích mở rộng libsodium PHP cho mã hóa hiện đại, an toàn và nhanh chóng

Cài đặt

libsodium (và, nếu bạn đang sử dụng các gói nhị phân, trên một số bản phân phối, thì cũng phải cài đặt libsodium-dev) trước tiện ích mở rộng này

Sau đó, sử dụng trình quản lý tiện ích mở rộng PHP

________số 8_______

Trên một số bản phân phối Linux như Debian, bạn có thể phải cài đặt PECL (

$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
0), gói phát triển PHP (
$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
1) và trình biên dịch (
$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
2) trước khi chạy lệnh này

libsodium-php 1. x API tương thích cho libsodium-php 2. x

Đối với các dự án sử dụng 1. x hoặc sẵn sàng sử dụng nó, lớp tương thích có sẵn

Polyfill Libsodium mang không gian tên

$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
3 trở lại

ví dụ

Mã hóa một tin nhắn bằng khóa bí mật

mã hóa

$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);

giải mã

$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);

Làm thế nào nó hoạt động

$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
4 là một khóa bí mật. Không phải mật khẩu. Đó là dữ liệu nhị phân, không phải thứ được thiết kế để con người có thể đọc được, mà là để có một không gian khóa càng lớn càng tốt trong một độ dài nhất định. Hàm
$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
5 tạo một khóa như vậy. Điều đó phải được giữ bí mật, vì nó được sử dụng để mã hóa và giải mã dữ liệu

$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
6 là một giá trị duy nhất. Giống như bí mật, độ dài của nó là cố định. Nhưng nó không nhất thiết phải là bí mật và có thể được gửi cùng với tin nhắn được mã hóa. Nonce cũng không phải là không thể đoán trước. Nó chỉ phải là duy nhất cho một khóa nhất định. Với API
$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
7, sử dụng
$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
8 là một cách hoàn toàn tốt để tạo nonces

Thư được mã hóa lớn hơn một chút so với thư không được mã hóa, vì chúng bao gồm trình xác thực, được sử dụng bởi chức năng giải mã để kiểm tra xem nội dung có bị thay đổi không

Mã hóa một tin nhắn bằng khóa bí mật và ẩn độ dài của nó

mã hóa

$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';
$blockSize = 16;

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$paddedMessage = sodium_pad($message, $blockSize);
$encryptedMessage = sodium_crypto_secretbox($paddedMessage, $nonce, $secretKey);

giải mã

$decryptedPaddedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
$decryptedMessage = sodium_unpad($decryptedPaddedMessage, $blockSize);

Làm thế nào nó hoạt động

Đôi khi, độ dài của một tin nhắn có thể cung cấp nhiều thông tin về bản chất của nó. Nếu một tin nhắn là một trong số "có", "không" và "có thể", mã hóa tin nhắn không giúp được gì. biết độ dài là đủ để biết tin nhắn là gì

Đệm là một kỹ thuật để giảm thiểu điều này, bằng cách làm cho độ dài bội số của một kích thước khối nhất định

Tin nhắn phải được đệm trước khi mã hóa và bỏ đệm sau khi giải mã

Mã hóa tệp bằng khóa bí mật

$secretKey = sodium_crypto_secretstream_xchacha20poly1305_keygen();
$inputFile = '/tmp/example.original';
$encryptedFile = '/tmp/example.enc';
$chunkSize = 4096;

$fdIn = fopen($inputFile, 'rb');
$fdOut = fopen($encryptedFile, 'wb');

[$stream, $header] = sodium_crypto_secretstream_xchacha20poly1305_init_push($secretKey);

fwrite($fdOut, $header);

$tag = SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE;
do {
    $chunk = fread($fdIn, $chunkSize);

    if (feof($fdIn)) {
        $tag = SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL;
    }

    $encryptedChunk = sodium_crypto_secretstream_xchacha20poly1305_push($stream, $chunk, '', $tag);
    fwrite($fdOut, $encryptedChunk);
} while ($tag !== SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL);

fclose($fdOut);
fclose($fdIn);

giải mã tập tin

$decryptedFile = '/tmp/example.dec';

$fdIn = fopen($encryptedFile, 'rb');
$fdOut = fopen($decryptedFile, 'wb');

$header = fread($fdIn, SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES);

$stream = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $secretKey);
do {
    $chunk = fread($fdIn, $chunkSize + SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES);
    [$decryptedChunk, $tag] = sodium_crypto_secretstream_xchacha20poly1305_pull($stream, $chunk);

    fwrite($fdOut, $decryptedChunk);
} while (!feof($fdIn) && $tag !== SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL);
$ok = feof($fdIn);

fclose($fdOut);
fclose($fdIn);

if (!$ok) {
    die('Invalid/corrupted input');
}

Làm thế nào nó hoạt động

Có nhiều mã hơn một chút so với các ví dụ trước

Trên thực tế,

$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive information';

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
9 sẽ hoạt động để mã hóa dưới dạng tệp, nhưng chỉ khi tệp đó khá nhỏ. Vì chúng tôi phải cung cấp toàn bộ nội dung dưới dạng một chuỗi nên nội dung đó phải vừa với bộ nhớ

Nếu tệp lớn, chúng tôi có thể chia tệp thành các phần nhỏ và mã hóa từng phần riêng lẻ

Bằng cách đó, chúng tôi có thể mã hóa các tệp lớn tùy ý. Nhưng chúng tôi cần đảm bảo rằng các khối không thể bị xóa, cắt bớt, sao chép và sắp xếp lại. Nói cách khác, chúng tôi không có một "tin nhắn" duy nhất, mà là một luồng tin nhắn và trong quá trình giải mã, chúng tôi cần một cách để kiểm tra xem toàn bộ luồng có khớp với những gì chúng tôi đã mã hóa không

Vì vậy, chúng tôi tạo một luồng mới (

$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
0) và đẩy một chuỗi thông báo vào đó (
$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
1). Theo mặc định, mỗi tin nhắn riêng lẻ đều có một thẻ đính kèm, theo mặc định là
$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
2. Để quá trình giải mã biết được nơi kết thúc luồng, chúng tôi gắn thẻ tin nhắn cuối cùng bằng thẻ
$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
3

Khi chúng tôi sử dụng luồng (

$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
4, sau đó là
$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
5 cho mỗi tin nhắn), chúng tôi kiểm tra xem chúng có thể được giải mã đúng cách hay không và truy xuất cả các đoạn được giải mã và các thẻ được đính kèm. Nếu chúng tôi đọc đoạn cuối cùng (
$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
3) và chúng tôi đang ở cuối tệp, chúng tôi biết rằng chúng tôi đã khôi phục hoàn toàn luồng ban đầu

Mã hóa tệp bằng khóa lấy từ mật khẩu

$password = 'password';
$inputFile = '/tmp/example.original';
$encryptedFile = '/tmp/example.enc';
$chunkSize = 4096;

$alg = SODIUM_CRYPTO_PWHASH_ALG_DEFAULT;
$opsLimit = SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE;
$memLimit = SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE;
$salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);

$secretKey = sodium_crypto_pwhash(
    SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES,
    $password,
    $salt,
    $opsLimit,
    $memLimit,
    $alg
);

$fdIn = fopen($inputFile, 'rb');
$fdOut = fopen($encryptedFile, 'wb');

fwrite($fdOut, pack('C', $alg));
fwrite($fdOut, pack('P', $opsLimit));
fwrite($fdOut, pack('P', $memLimit));
fwrite($fdOut, $salt);

[$stream, $header] = sodium_crypto_secretstream_xchacha20poly1305_init_push($secretKey);

fwrite($fdOut, $header);

$tag = SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE;
do {
    $chunk = fread($fdIn, $chunkSize);
    if (feof($fdIn)) {
        $tag = SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL;
    }

    $encryptedChunk = sodium_crypto_secretstream_xchacha20poly1305_push($stream, $chunk, '', $tag);
    fwrite($fdOut, $encryptedChunk);
} while ($tag !== SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL);

fclose($fdOut);
fclose($fdIn);

Đọc các tham số được lưu trữ và giải mã tệp

$decryptedFile = '/tmp/example.dec';

$fdIn = fopen($encryptedFile, 'rb');
$fdOut = fopen($decryptedFile, 'wb');

$alg = unpack('C', fread($fdIn, 1))[1];
$opsLimit = unpack('P', fread($fdIn, 8))[1];
$memLimit = unpack('P', fread($fdIn, 8))[1];
$salt = fread($fdIn, SODIUM_CRYPTO_PWHASH_SALTBYTES);

$header = fread($fdIn, SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES);

$secretKey = sodium_crypto_pwhash(
    SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES,
    $password,
    $salt,
    $opsLimit,
    $memLimit,
    $alg
);

$stream = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $secretKey);
do {
    $chunk = fread($fdIn, $chunkSize + SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES);
    $res = sodium_crypto_secretstream_xchacha20poly1305_pull($stream, $chunk);

    if ($res === false) {
        break;
    }
    
    [$decrypted_chunk, $tag] = $res;
    fwrite($fdOut, $decrypted_chunk);
} while (!feof($fdIn) && $tag !== SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL);
$ok = feof($fdIn);

fclose($fdOut);
fclose($fdIn);

if (!$ok) {
    die('Invalid/corrupted input');
}

Làm thế nào nó hoạt động

Không thể sử dụng trực tiếp mật khẩu làm khóa bí mật. Mật khẩu ngắn, phải gõ được trên bàn phím và những người không sử dụng trình quản lý mật khẩu có thể nhớ chúng

Mật khẩu 8 ký tự theo cách này yếu hơn khóa 8 byte

Hàm

$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
7 thực hiện một thao tác tính toán chuyên sâu trên mật khẩu để lấy khóa bí mật

Bằng cách đó, việc sử dụng vũ phu tất cả các mật khẩu có thể để tìm khóa bí mật được sử dụng để mã hóa dữ liệu trở thành một hoạt động tốn kém

Có thể sử dụng nhiều thuật toán để lấy khóa từ mật khẩu và đối với mỗi thuật toán, có thể chọn các tham số khác nhau. Điều quan trọng là lưu trữ tất cả những thứ này cùng với dữ liệu được mã hóa. Sử dụng cùng một thuật toán và cùng các tham số, cùng một khóa bí mật có thể được tính toán lại một cách xác định

Làm cách nào để bật libsodium trong PHP?

ea-php74 trở lên qua EasyApache trong WHM .
Đăng nhập vào WHM với tư cách là người dùng root
Hướng đến. Trang chủ » Phần mềm » EasyApache 4
Nhấp vào nút "Tùy chỉnh" màu xanh lam
Nhấp vào liên kết "Tiện ích mở rộng PHP" ở thanh bên trái
Nhập libsodium vào hộp tìm kiếm
Chuyển đổi phần mở rộng libsodium để nó chuyển sang màu xanh cho mỗi phiên bản PHP mong muốn

Libsodium trong PHP là gì?

Libsodium, còn được gọi là Natri, là thư viện mật mã mạnh mẽ . Nó là một nhánh rẽ di động, có thể biên dịch chéo, có thể cài đặt và có thể đóng gói của NaCl, một công cụ mật mã nổi tiếng được thiết kế bởi Giáo sư. Đ. J. Bernstein. Nếu bạn cần bật mã hóa/giải mã PHP, bạn có thể sử dụng Libsodium.

Làm cách nào tôi có thể cài đặt tiện ích mở rộng PHP Libsodium trong máy chủ xampp?

14 sau đó cài đặt thêm natri và nó hoạt động. .
Cài đặt XAMPP(xampp-win32-7. 1. 14-0-VC14)
Tải xuống libsodium có tên php_libsodium-2. 0. 9-7. 1-ts-vc14-x86. khóa kéo
Đổi tên php_sodium. dll sang php_libsodium. dll rồi cho vào C. \xampp\php\ext
Đặt libsodium. dll vào C. \xampp\apache\bin

Làm cách nào để cài đặt libsodium?

Cài đặt Libsodium (chỉ dành cho Windows và MacOS) .
Giải nén các tệp từ tệp zip
Có hai thư mục giải nén. x64 và Win32. Chọn x64 cho 64-bit hoặc Win32 cho phiên bản Windows 32-bit và tìm kiếm libsodium. dll. .
Sao chép libsodium này. dll và dán vào C. \Windows\system32