美文网首页
php RSA 加密 解密 验签

php RSA 加密 解密 验签

作者: sowork | 来源:发表于2018-09-16 20:35 被阅读87次

    注:加密的内容长度是有限制的,具体可参考

    密钥生成

    https://www.jianshu.com/p/9dc5c8a93308

    https://blog.csdn.net/li396864285/article/details/79865806

    A为客户端 B为服务端

    A手里有一套密钥(私钥A/公钥A)

    B手里有一套密钥(私钥B/公钥B)

    A将公钥A发给B

    B将公钥B发给A

    注:两套公钥目的是为了保证确实是AB双方在通信,双方的私钥加签是为了标明自己的身份,如果只是对数据进行保护,防止被窃取,服务器只颁发一套密钥也可以

    A向B发送请求流程:

    2. A用 私钥A + msg获取签名SignA

    3. A用 公钥B 将SignA + msg 加密 得到 要发送的密文 secret

    4. B 收到 A 发送过来的密文 secret 使用 私钥B 进行解密 得到 SignA + msg (第一次解密)

    5. B 使用 公钥B + msg +signA进行验签操作(第二次验签)

    引用别处的图片

    image
    
    /**
    
    * Created by PhpStorm.
    
    * User: 80752
    
    * Date: 2018/9/12
    
    * Time: 21:30
    
    */
    
    if (! function_exists('url_safe_base64_encode')) {
    
        function url_safe_base64_encode ($data) {
    
            return str_replace(array('+','/', '='),array('-','_', ''), base64_encode($data));
    
        }
    
    }
    
    if (! function_exists('url_safe_base64_decode')) {
    
        function url_safe_base64_decode ($data) {
    
            $base_64 = str_replace(array('-','_'),array('+','/'), $data);
    
            return base64_decode($base_64);
    
        }
    
    }
    
    class RSA
    
    {
    
        /**
    
        * 选择在创建CSR时应该使用哪些扩展。可选值有 OPENSSL_KEYTYPE_DSA, OPENSSL_KEYTYPE_DH, OPENSSL_KEYTYPE_RSA 或 OPENSSL_KEYTYPE_EC. 默认值是 OPENSSL_KEYTYPE_RSA.
    
    */
    
        const RSA_ALGORITHM_KEY_TYPE = OPENSSL_KEYTYPE_RSA;
    
        /**
    
        * 签名算法, 默认为 OPENSSL_ALGO_SHA1
    
    */
    
        const RSA_ALGORITHM_SIGN = OPENSSL_ALGO_SHA256;
    
        /**
    
        * 公钥
    
        * @var string
    
    */
    
        public static $publicKey = '';
    
        /**
    
        * 私钥
    
        * @var string
    
    */
    
        public static $privateKey = '';
    
        public static function createRsaKey ($key_size = 2048) {
    
            $config = array(
    
                "private_key_bits" => $key_size,
    
                "private_key_type" => self::RSA_ALGORITHM_KEY_TYPE
    
            );
    
            $res = openssl_pkey_new($config);
    
            openssl_pkey_export($res, $private_key);
    
            $public_key_detail = openssl_pkey_get_details($res);
    
            $public_key = $public_key_detail["key"];
    
            self::$publicKey = $public_key;
    
            self::$privateKey = $private_key;
    
            return [
    
                "public_key" => $public_key,
    
                "private_key" => $private_key,
    
            ];
    
        }
    
        /**
    
        * 获取rsa密钥加密位数
    
        * @param $source
    
        * @return mixed
    
    */
    
        private static function getKeyBitDetail ($source) {
    
            return openssl_pkey_get_details($source)['bits'];
    
        }
    
        /**
    
        * 获取私钥
    
        * @return bool|resource
    
    */
    
        public static function getPrivateKey () {
    
            $source =  openssl_pkey_get_private('file://rsa_private_key.pem');
    
            if (!$source) {
    
                $source = openssl_pkey_get_private(self::$privateKey);
    
            }
    
            return $source;
    
        }
    
        /**
    
        * 获取公钥
    
        * @return resource
    
    */
    
        public static function getPublicKey () {
    
            $source = openssl_pkey_get_public('file://rsa_public_key.pem');
    
            if (!$source) {
    
                $source = openssl_pkey_get_public(self::$publicKey);
    
            }
    
            return $source;
    
        }
    
        /**
    
        * 私钥加密
    
        * @param $data
    
        * @return bool|null
    
    */
    
        public static function privEncrypt ($data = '') {
    
            $privKey = self::getPrivateKey();
    
            $partLen = self::getKeyBitDetail($privKey) / 8 - 11;
    
            $parts = str_split($data, $partLen);
    
            $encrypted = '';
    
            foreach ($parts as $part) {
    
                openssl_private_encrypt($part, $partEncrypt, $privKey);
    
                $encrypted .= $partEncrypt;
    
            }
    
            openssl_free_key($privKey);
    
            return $encrypted ? url_safe_base64_encode($encrypted) : null;
    
        }
    
        /**
    
        * 公钥解密
    
        * @param string $encrypted
    
        * @return bool|null
    
    */
    
        public static function publicDecrypt ($encrypted = '') {
    
            $pubKey = self::getPublicKey();
    
            $partLen = self::getKeyBitDetail($pubKey) / 8;
    
            $parts = str_split(url_safe_base64_decode($encrypted), $partLen);
    
            $decrypted = '';
    
            foreach ($parts as $part) {
    
                openssl_public_decrypt($part, $partDecrypt, $pubKey);
    
                $decrypted .= $partDecrypt;
    
            }
    
            openssl_free_key($pubKey);
    
            return $decrypted ?: null;
    
        }
    
        /**
    
        * 公钥加密
    
        * @param string $data
    
        * @return bool|null
    
    */
    
        public static function publicEncrypt ($data = '') {
    
            $pubKey = self::getPublicKey();
    
            $partLen = self::getKeyBitDetail($pubKey) / 8 - 11;
    
            $parts = str_split($data, $partLen);
    
            $encrypted = '';
    
            foreach ($parts as $part) {
    
                openssl_public_encrypt($part, $partEncrypt, $pubKey);
    
                $encrypted .= $partEncrypt;
    
            }
    
            openssl_free_key($pubKey);
    
            return $encrypted ? url_safe_base64_encode($encrypted) : null;
    
        }
    
        /**
    
        * 私钥解密
    
        * @param string $encrypted
    
        * @return bool|null
    
    */
    
        public static function privDecrypt ($encrypted = '') {
    
            $privKey = self::getPrivateKey();
    
            $partLen = self::getKeyBitDetail($privKey) / 8;
    
            $parts = str_split(url_safe_base64_decode($encrypted), $partLen);
    
            $decrypted = '';
    
            foreach ($parts as $part) {
    
                openssl_private_decrypt($part, $partDecrypt, $privKey);
    
                $decrypted .= $partDecrypt;
    
            }
    
            openssl_free_key($privKey);
    
            return $decrypted ?: null;
    
        }
    
        /**
    
        * 私钥签名
    
        * @param string $data
    
        * @return null|string
    
    */
    
        public static function privSign ($data = '') {
    
            $privKey = self::getPrivateKey();
    
            openssl_sign($data, $sign, $privKey, self::RSA_ALGORITHM_SIGN);
    
            openssl_free_key($privKey);
    
            return $sign ? url_safe_base64_encode($sign) : null;
    
        }
    
        /**
    
        * 公钥验签
    
        * @param string $data
    
        * @param string $sign
    
        * @return int
    
    */
    
        public static function publicVerifySign ($data = '', $sign = '') {
    
            $pubKey = self::getPublicKey();
    
            $res = openssl_verify($data, url_safe_base64_decode($sign), $pubKey, self::RSA_ALGORITHM_SIGN);
    
            openssl_free_key($pubKey);
    
            return $res;
    
        }
    
    }
    
    $data['name'] = 'sowork111111111111111111111111111111111111111111111111sowork1111111111111111111111111111111111112313111111111111111111111111===============================================';
    
    $data['age'] = '24';
    
    echo '<pre>';
    
    print_r(RSA::createRsaKey()) . '<br/>';
    
    echo '</pre>';
    
    // 私钥加密 公钥解密
    
    //$privSec = RSA::privEncrypt(json_encode($data));
    
    //echo '私钥加密:' . $privSec . '<br/>';
    
    //echo '公钥解密:' . RSA::publicDecrypt($privSec) . '<br/>';
    
    // 公钥加密 私钥解密
    
    //$pubSec = RSA::publicEncrypt(json_encode($data));
    
    //echo '公钥加密:' . $pubSec . '<br/>';
    
    //echo '私钥解密:' . RSA::privDecrypt($pubSec) . '<br/>';
    
    $sign = RSA::privSign(json_encode($data));
    
    $secret = RSA::publicEncrypt(json_encode($data));
    
    echo '私钥签名后:' . $sign . ' <br/>';
    
    echo '公钥验签后:' . RSA::publicVerifySign(json_encode($data), $sign) . '<br/>';
    
    

    相关文章

      网友评论

          本文标题:php RSA 加密 解密 验签

          本文链接:https://www.haomeiwen.com/subject/fpifnftx.html