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