Các loại mã hóa:
Trong thiết kế và phát triển hàng ngày, để đảm bảo an toàn cho việc truyền tải và lưu trữ dữ liệu, có thể sử dụng các thuật toán cụ thể để mã hóa dữ liệu gốc thành văn bản mã phức tạp. Hiện tại, các phương pháp mã hóa chính có thể được chia thành mã hóa một chiều và mã hóa hai chiều. Mã hóa một chiều: Tính toán tóm tắt dữ liệu để tạo ra văn bản mã, không thể đảo ngược để tìm lại dữ liệu gốc. Các thuật toán tiêu biểu: Base64, MD5, SHA. Mã hóa hai chiều: Ngược lại với một chiều, có thể đảo ngược văn bản mã để lấy lại dữ liệu gốc. Mã hóa hai chiều được chia thành mã hóa đối xứng và mã hóa bất đối xứng. Mã hóa đối xứng: Người dùng dữ liệu phải có cùng một khóa để thực hiện mã hóa và giải mã, giống như một mật mã thỏa thuận giữa các bên. Các thuật toán tiêu biểu: DES, 3DES, AES, IDEA, RC4, RC5. Mã hóa bất đối xứng: So với mã hóa đối xứng, không cần có cùng một bộ khóa. Mã hóa bất đối xứng là một "giao thức trao đổi khóa công khai". Nó yêu cầu hai bộ khóa: khóa công khai và khóa riêng tư, được ghép đôi với nhau. Nghĩa là, khi mã hóa dữ liệu bằng khóa công khai, chỉ có khóa riêng tư tương ứng mới có thể giải mã. Hai khóa này liên quan đến mặt toán học; văn bản mã được mã hóa bằng khóa của một người dùng chỉ có thể giải mã bằng khóa mã hóa của người đó. Nếu biết một trong hai khóa, không thể tính toán ra khóa kia. Vì vậy, nếu công khai một trong hai khóa, điều đó không làm ảnh hưởng đến tính chất của khóa còn lại. Ở đây, khóa được công khai gọi là khóa công khai, khóa không được công khai gọi là khóa riêng tư. Các thuật toán tiêu biểu: RSA, DSA.
Trước đây, tôi thường bối rối về việc mã hóa thông tin từ máy khách gửi đến máy chủ. Nếu thông tin đăng nhập của người dùng trong ứng dụng bị bắt gói, hiển thị rõ ràng username: root, password: 123456, thì thật khó xử.
Tình cờ khi làm việc với bản quyền đầu vào, tôi đã gặp RSA; trong quá trình thanh toán qua Alipay cũng đã tiếp xúc với nó, nhưng lúc đó không biết nó là gì, bây giờ mới biết.
Nó đảm bảo rằng thông tin từ máy khách chỉ có máy chủ có khóa riêng tư mới có thể đọc, người khác chỉ thấy toàn ký tự lộn xộn.
Thuật toán mã hóa bất đối xứng
Cần hai khóa: khóa công khai (publickey) và khóa riêng tư (privatekey). Khóa công khai và khóa riêng tư là một cặp. Nếu dùng khóa công khai để mã hóa dữ liệu, chỉ có khóa riêng tư tương ứng mới giải mã được. Nếu dùng khóa riêng tư để mã hóa dữ liệu, chỉ có khóa công khai tương ứng mới giải mã được. Vì quá trình mã hóa và giải mã sử dụng hai khóa khác nhau, thuật toán này được gọi là mã hóa bất đối xứng.
Lưu ý một điểm: dữ liệu được mã hóa bằng khóa công khai chỉ có thể giải mã bằng khóa riêng tư tương ứng.
Trong sử dụng hàng ngày, nó hoạt động như sau:
Đặt khóa riêng tư private_key.pem ở phía máy chủ, phát hành khóa công khai cho các front-end như Android và iOS.
Máy khách sau khi mã hóa dữ liệu bằng khóa công khai, dữ liệu chỉ có thể được máy chủ có khóa riêng tư duy nhất hiểu.
Triển khai cụ thể:
1. Bước đầu tiên của mã hóa và giải mã là tạo cặp khóa công khai và khóa riêng tư. Nội dung được mã hóa bằng khóa riêng tư có thể được giải mã bằng khóa công khai (và ngược lại).
1. Tải công cụ mã nguồn mở openssl để tạo khóa RSA (thông thường hệ thống Linux đã có sẵn), giải nén vào thư mục riêng, vào thư mục bin, thực hiện các lệnh sau: 2. a. openssl genrsa -out rsa_private_key.pem 1024 3. b. openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem 4. c. openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 5. 6. Lệnh đầu tiên tạo tệp khóa riêng tư RSA gốc rsa_private_key.pem 7. Lệnh thứ hai chuyển đổi khóa riêng tư RSA gốc thành định dạng pkcs8 8. Lệnh thứ ba tạo khóa công khai RSA rsa_public_key.pem 9. 10. Từ đó có thể thấy: thông qua khóa riêng tư, có thể tạo ra khóa công khai tương ứng.
Cũng có một số trang web cung cấp dịch vụ tạo khóa công khai và khóa riêng tư RSA: http://www.bm8.com.cn/webtool/rsa/
2. Thư viện mã hóa và giải mã PHP:
<?php
class CryptoRsa {
/**
* Lấy khóa riêng tư
* @return bool|resource
*/
private static function fetchPrivateKey()
{
$filePath = dirname(__FILE__) . '/rsa_private_key.pem';
$keyContent = file_get_contents($filePath);
return openssl_pkey_get_private($keyContent);
}
/**
* Lấy khóa công khai
* @return bool|resource
*/
private static function fetchPublicKey()
{
$filePath = dirname(__FILE__) . '/rsa_public_key.pem';
$keyContent = file_get_contents($filePath);
return openssl_pkey_get_public($keyContent);
}
/**
* Mã hóa bằng khóa riêng tư
* @param string $data
* @return null|string
*/
public static function encryptWithPrivateKey($data = '')
{
if (!is_string($data)) {
return null;
}
$result = openssl_private_encrypt($data, $encryptedOutput, self::fetchPrivateKey());
return $result ? base64_encode($encryptedOutput) : null;
}
/**
* Mã hóa bằng khóa công khai
* @param string $data
* @return null|string
*/
public static function encryptWithPublicKey($data = '')
{
if (!is_string($data)) {
return null;
}
$result = openssl_public_encrypt($data, $encryptedOutput, self::fetchPublicKey());
return $result ? base64_encode($encryptedOutput) : null;
}
/**
* Giải mã bằng khóa riêng tư
* @param string $encryptedData
* @return null|string
*/
public static function decryptWithPrivateKey($encryptedData = '')
{
if (!is_string($encryptedData)) {
return null;
}
$success = openssl_private_decrypt(base64_decode($encryptedData), $decryptedOutput, self::fetchPrivateKey());
return $success ? $decryptedOutput : null;
}
/**
* Giải mã bằng khóa công khai
* @param string $encryptedData
* @return null|string
*/
public static function decryptWithPublicKey($encryptedData = '')
{
if (!is_string($encryptedData)) {
return null;
}
$success = openssl_public_decrypt(base64_decode($encryptedData), $decryptedOutput, self::fetchPublicKey());
return $success ? $decryptedOutput : null;
}
}
Ví dụ gọi hàm:
<?php require_once "CryptoRsa.php"; $userData = ['name' => 'Tom', 'age' => '20']; $jsonData = json_encode($userData); $encryptedByPrivate = CryptoRsa::encryptWithPrivateKey($jsonData); echo 'Dữ liệu đã mã hóa bằng khóa riêng tư: ' . $encryptedByPrivate . '<br>'; $decryptedByPublic = CryptoRsa::decryptWithPublicKey($encryptedByPrivate); echo 'Dữ liệu đã giải mã bằng khóa công khai: ' . $decryptedByPublic . '<br>'; $encryptedByPublic = CryptoRsa::encryptWithPublicKey($jsonData); echo 'Dữ liệu đã mã hóa bằng khóa công khai: ' . $encryptedByPublic . '<br>'; $decryptedByPrivate = CryptoRsa::decryptWithPrivateKey($encryptedByPublic); echo 'Dữ liệu đã giải mã bằng khóa riêng tư: ' . $decryptedByPrivate . '<br>';
