123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <?php
- namespace App\Service;
- class RsaEncryptionService extends Service
- {
- // public function encrypt($data)
- // {
- // //公钥文件位于 storage/app/public/rsa/public.pem
- // $publicKeyPath = storage_path('app/public/rsa/public.pem');
- // $publicKey = openssl_pkey_get_public(file_get_contents($publicKeyPath));
- //
- // openssl_public_encrypt($data, $encrypted, $publicKey);
- // return base64_encode($encrypted);
- // }
- public function encrypt($data){
- $data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); // 重新序列化,确保所有key按字典序排序
- // 公钥文件位于 storage/app/public/rsa/public.pem
- $publicKeyPath = storage_path('app/public/rsa/public.pem');
- // 确保文件存在
- if (!file_exists($publicKeyPath)) return [false , '公钥不存在'];
- // 读取公钥文件的内容
- $publicKeyContent = file_get_contents($publicKeyPath);
- if ($publicKeyContent === false) return [false , '公钥文件读取失败'];
- // 获取公钥资源
- $publicKey = openssl_pkey_get_public($publicKeyContent);
- if (! $publicKey) {
- $error = openssl_error_string();
- if ($error !== false) {
- return [false , '公钥文件加载失败:' . $error];
- } else {
- return [false , '公钥文件加载失败'];
- }
- }
- // 假设 $publicKey 是你已经获取的公钥资源
- // $keyDetails = openssl_pkey_get_details($publicKey);
- // $keyBits = $keyDetails['bits'];
- // PKCS#1 v1.5 填充的最大数据长度
- // $maxDataLengthPkcs1 = floor($keyBits / 8) - 11;
- // OAEP 填充的最大数据长度
- // $maxDataLengthOaep = floor($keyBits / 8) - 42;
- // echo "For PKCS#1 v1.5 padding, the maximum data length is: {$maxDataLengthPkcs1} bytes.\n";
- // echo "For OAEP padding, the maximum data length is: {$maxDataLengthOaep} bytes.\n";
- if (! openssl_public_encrypt($data, $encrypted, $publicKey)) {
- $error = openssl_error_string();
- if ($error !== false) {
- return [false , '加密失败:' . $error];
- } else {
- return [false , '加密失败'];
- }
- }
- // 返回base64编码的加密数据
- return [true, base64_encode($encrypted)];
- }
- function encrypt2($data) {
- // 公钥文件
- $publicKeyString = storage_path('app/public/rsa/public.pem');
- // 读取公钥文件内容
- $publicKeyString = file_get_contents($publicKeyString);
- //加密的数据
- $plainText = json_encode($data);
- // 生成随机AES密钥以进行对称加密
- $aesKey = openssl_random_pseudo_bytes(16); // AES-128
- // 使用AES加密明文
- $ivlen = openssl_cipher_iv_length('aes-128-cbc');
- $iv = openssl_random_pseudo_bytes($ivlen);
- $encryptedBytes = openssl_encrypt($plainText, 'aes-128-cbc', $aesKey, OPENSSL_RAW_DATA, $iv);
- // 使用RSA加密AES密钥
- $resource = openssl_pkey_get_public($publicKeyString);
- openssl_public_encrypt($aesKey, $encryptedAESKey, $resource);
- // 组合AES密钥和加密的消息
- $encryptedAESKeyStr = base64_encode($encryptedAESKey);
- $encryptedMessageStr = base64_encode($iv . $encryptedBytes);
- //AES的密钥 : 传递的参数
- return $encryptedAESKeyStr . ":" . $encryptedMessageStr;
- }
- function decrypt2($encryptedText) {
- // 密钥文件
- $privateKeyString = storage_path('app/public/rsa/private.pem');
- // 读取密钥文件内容
- $privateKeyString = file_get_contents($privateKeyString);
- // 将输入分成加密的AES密钥和加密的消息两部分
- list($encryptedAESKeyStr, $encryptedMessageStr) = explode(":", $encryptedText, 2);
- if (!isset($encryptedAESKeyStr) || !isset($encryptedMessageStr)) {
- throw new \Exception("无效的输入格式");
- }
- // 使用RSA私钥解密AES密钥
- $resource = openssl_pkey_get_private($privateKeyString);
- $encryptedAESKey = base64_decode($encryptedAESKeyStr);
- openssl_private_decrypt($encryptedAESKey, $decryptedAESKey, $resource);
- // 使用AES解密消息
- $ivlen = openssl_cipher_iv_length('aes-128-cbc');
- $encryptedMessage = base64_decode($encryptedMessageStr);
- $iv = substr($encryptedMessage, 0, $ivlen);
- $ciphertext = substr($encryptedMessage, $ivlen);
- $plaintext = openssl_decrypt($ciphertext, 'aes-128-cbc', $decryptedAESKey, OPENSSL_RAW_DATA, $iv);
- return $plaintext;
- }
- // 加密函数
- function aesEncrypt($data) {
- $data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); // 重新序列化,确保所有key按字典序排序
- // 密钥文件
- $key = storage_path('app/public/rsa/public.pem');
- // 读取密钥文件内容
- $key = file_get_contents($key);
- // 生成一个随机的初始化向量(IV)
- $ivSize = openssl_cipher_iv_length('aes-256-cbc');
- $iv = openssl_random_pseudo_bytes($ivSize);
- // 加密数据
- $encrypted = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
- if ($encrypted === false) return [false, '加密失败'];
- // 将 IV 和加密后的数据一起返回,以便解密时使用
- return [true, base64_encode($iv) . ":" . base64_encode($encrypted)];
- }
- // 解密函数
- function aesDecrypt($data) {
- // 公钥文件位于 storage/app/public/rsa/public.pem
- $key = storage_path('app/public/rsa/public.pem');
- // 读取密钥文件内容
- $key = file_get_contents($key);
- // 分割字符串,去除冒号
- list($ivPart, $encryptedPart) = explode(':', $data, 2);
- $ivPart = base64_decode($ivPart);
- $encryptedPart = base64_decode($encryptedPart);
- // 获取 IV 和加密后的数据
- $ivSize = openssl_cipher_iv_length('aes-256-cbc');
- $iv = substr($ivPart, 0, $ivSize);
- $encrypted = $encryptedPart;
- // 解密数据
- $decrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
- if ($decrypted === false) {
- throw new \Exception('Decryption failed.');
- }
- return $decrypted;
- }
- }
|