PHP 实现 RSA 公私钥加密

文章目录 (?) [+]

    一个简易的 RSA 公私钥生成、签名、验签、加密、解密的类。

    <?php
    /**
     * RSA
     *
     * @version     1.0.0
     * @author      Wildlife <admin@lanseyujie.com>
     * @link        https://lanseyujie.com
     * @copyright   Copyright(c) 2015-2019, lanseyujie.com
     */
    
    class Rsa
    {
        public $path = './';
        public $keyBits = 1024;
        public $publicKey = null;
        public $privateKey = null;
        
        public function __construct()
        {
            if (file_exists($this->path . 'public.key') && file_exists($this->path . 'private.key')) {
                $this->publicKey = file_get_contents($this->path . 'public.key');
                $this->privateKey = file_get_contents($this->path . 'private.key');
            } else if ($this->createKey()) {
                $this->publicKey = file_get_contents($this->path . 'public.key');
                $this->privateKey = file_get_contents($this->path . 'private.key');
            } else {
                exit;
            }
        }
    
        /**
         * Create Key
         *
         * @return bool
         */
        public function createKey()
        {
            $path = $this->path;
            $bits = $this->keyBits;
            $config = array(
                'private_key_bits' => (int)$bits,
            );
            $res = openssl_pkey_new($config);
            openssl_pkey_export($res, $privateKey);
            $publicKey = openssl_pkey_get_details($res);
            $publicKey = $publicKey['key'];
            if (file_exists($path)) {
                file_put_contents($path . 'private.key', $privateKey);
                file_put_contents($path . 'public.key', $publicKey);
    
                return true;
            }
        
            return false;
        }
    
        /**
         * Signature
         *
         * @param string $plainText
         * @return string
         */
        public function sign($plainText)
        {
            $privateKey = $this->privateKey;
            $key = openssl_get_privatekey($privateKey);
            openssl_sign($plainText, $sign, $key);
            $sign = base64_encode($sign);
            openssl_free_key($key);
    
            return $sign;
        }
    
        /**
         * Verify Signature
         *
         * @param string $plainText
         * @param string $sign
         * @return string
         */
        public function verify($plainText, $sign)
        {
            $publicKey = $this->publicKey;
            $key = openssl_get_publickey($publicKey);
            $sign = base64_decode($sign);
            $result = (bool)openssl_verify($plainText, $sign, $key);
            openssl_free_key($key);
    
            return $result;
        }
    
        #############################################################################################
    
        /**
         * Encrypt Plain Text By Public Key
         *
         * @param string $plainText
         * @return string
         */
        public function encryptByPublicKey($plainText)
        {
            $publicKey = $this->publicKey;
            $key = openssl_get_publickey($publicKey);
            $result  = '';
            for ($i = 0; $i < (strlen($plainText) / 128); $i++) {
                $data = substr($plainText, $i * 128, 128);
                openssl_public_encrypt($data, $encrypt, $key);
                $result .= $encrypt;
            }
            $result = base64_encode($result);
            openssl_free_key($key);
    
            return $result;
        }
    
        /**
         * Decrypt Cipher Text By Private key
         *
         * @param string $cipherText
         * @return string
         */
        public function decryptByPrivateKey($cipherText)
        {
            $privateKey = $this->privateKey;
            $key = openssl_get_privatekey($privateKey);
            $cipherText = base64_decode($cipherText);
            $result  = '';
            for ($i = 0; $i < (strlen($cipherText) / 128); $i++) {
                $data = substr($cipherText, $i * 128, 128);
                openssl_private_decrypt($data, $decrypt, $key);
                $result .= $decrypt;
            }
            openssl_free_key($key);
    
            return $result;
        }
    
        #############################################################################################
    
        /**
         * Encrypt Plain Text By Private key
         *
         * @param string $plainText
         * @param string $privateKey
         * @return string
         */
        public function encryptByPrivateKey($plainText)
        {
            $privateKey = $this->privateKey;
            $key = openssl_get_privatekey($privateKey);
            $result  = '';
            for ($i = 0; $i < (strlen($plainText) / 128); $i++) {
                $data = substr($plainText, $i * 128, 128);
                openssl_private_encrypt($data, $encrypt, $key);
                $result .= $encrypt;
            }
            $result = base64_encode($result);
            openssl_free_key($key);
    
            return $result;
        }
    
        /**
         * Decrypt Cipher Text By Public Key
         *
         * @param string $cipherText
         * @param string $privateKey
         * @return string
         */
        public function decryptByPublicKey($cipherText)
        {
            $publicKey = $this->publicKey;
            $key = openssl_get_publickey($publicKey);
            $cipherText = base64_decode($cipherText);
            $result  = '';
            for ($i = 0; $i < (strlen($cipherText) / 128); $i++) {
                $data = substr($cipherText, $i * 128, 128);
                openssl_public_decrypt($data, $decrypt, $key);
                $result .= $decrypt;
            }
            openssl_free_key($key);
    
            return $result;
        }
    }


    测试

    require 'rsa.class.php';
    
    $rsa = new Rsa();
    
    $text = 'Test Sign';
    echo $a = $rsa->sign($text) . "\n";
    var_dump($rsa->verify($text, $a)) . "\n";
    
    echo $b = $rsa->encryptByPublicKey('Hello World') . "\n";
    echo $rsa->decryptByPrivateKey($b) . "\n";
    
    echo $c = $rsa->encryptByPrivateKey('Hello') . "\n";
    echo $rsa->decryptByPublicKey($c) . "\n";

    测试 RSA 类


    OpenSSL 生成公私钥

    mkdir key && cd key
    sudo apt install openssl
    openssl
    genrsa -out private.pem 1024
    rsa -in private.pem -pubout -out public.pem
    exit

    OpenSSL 生成公私钥

    本文标题:PHP 实现 RSA 公私钥加密
    本文链接:https://www.lanseyujie.com/post/rsa-class-php.html
    版权声明:本文使用「署名-非商业性使用-相同方式共享」创作共享协议,转载或使用请遵守署名协议。
    点赞 0 分享 0
    上一篇:水滴信用 API