RSA 非对称加密&解密,超长字符串分块处理

封装一个非对称加密和解密实用类

<?php

class RsaServer
{
    /**
     * @var false|resource
     */
    protected $key;

    /**
     * 分隔符
     * @var string
     */
    protected $mark = '.';

    /**
     * 分片长度 
     * @var int 
     */
    protected $length = 245;

    /**
     * 获取秘钥
     * RsaServer constructor.
     * @param string $key_file
     * @param bool $is_pub
     * @throws FileNotFoundException
     */
    public function __construct(string $key_file, $is_pub = false)
    {
        if (!is_file($key_file)) {
            throw new \Exception('key path is invalid');
        }
        $content = file_get_contents($key_file);
        if ($is_pub) {
            $this->key = openssl_pkey_get_public($content);
        } else {
            $this->key = openssl_pkey_get_private($content);
        }

        return $this;
    }

    /**
     * 私钥加密
     * @param string $data
     * @return null|string
     */
    public function privEncrypt($data = '')
    {
        $result = [];
        if (!is_string($data)) {
            return null;
        } else if (strlen($data) > $this->length) {
            foreach (str_split($data, $this->length) as $chunk) {
                if (openssl_private_encrypt($chunk, $encrypted, $this->key)) {
                    $result[] = base64_encode($encrypted);
                } else {
                    return null;
                }
            }
            $result = implode($this->mark, $result);
        } else {
            $result = openssl_private_encrypt($data, $encrypted, $this->key) ? base64_encode($encrypted) : null;
        }

        return $result;
    }

    /**
     * 公钥加密
     * @param string $data
     * @return null|string
     */
    public function publicEncrypt($data = '')
    {
        $result = [];
        if (!is_string($data)) {
            return null;
        } else if (strlen($data) > $this->length) {
            foreach (str_split($data, $this->length) as $chunk) {
                if (openssl_public_encrypt($chunk, $encrypted, $this->key)) {
                    $result[] = base64_encode($encrypted);
                } else {
                    return null;
                }
            }
            $result = implode($this->mark, $result);
        } else {
            $result = openssl_public_encrypt($data, $encrypted, $this->key) ? base64_encode($encrypted) : null;
        }

        return $result;
    }

    /**
     * 私钥解密
     * @param string $encrypted
     * @return null
     */
    public function privDecrypt($encrypted = '')
    {
        $result = '';
        $encrypted_chunk = explode($this->mark, $encrypted);
        if (!is_string($encrypted)) {
            return null;
        } else if (count($encrypted_chunk) > 1) {
            foreach ($encrypted_chunk as $chunk) {
                if (openssl_private_decrypt(base64_decode($chunk), $decrypted, $this->key)) {
                    $result .= $decrypted;
                } else {
                    return null;
                }
            }
        } else {
            $result = openssl_private_decrypt(base64_decode($encrypted), $decrypted, $this->key) ? $decrypted : null;
        }

        return $result;
    }

    /**
     * 公钥解密
     * @param string $encrypted
     * @return null
     */
    public function publicDecrypt($encrypted = '')
    {
        $result = '';
        $encrypted_chunk = explode($this->mark, $encrypted);
        if (!is_string($encrypted)) {
            return null;
        } else if (count($encrypted_chunk) > 1) {
            foreach ($encrypted_chunk as $chunk) {
                if (openssl_public_decrypt(base64_decode($chunk), $decrypted, $this->key)) {
                    $result .= $decrypted;
                } else {
                    return null;
                }
            }
        } else {
            $result = openssl_public_decrypt(base64_decode($encrypted), $decrypted, $this->key) ? $decrypted : null;
        }

        return $result;
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 4

一般还会用到 签名/验签,可以把类丰富下 :smile:

3年前 评论
Rancy (楼主) 3年前
ilating 3年前

楼主,SM2非对称加密懂吗

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!