Karp 的技术博客

2024-08-20T12:33:49.png


<?php


class Rsa
{
    /**
     * 生成证书
     * @return array
     */
    public static function exportOpenSSLFile($bits = 1024)
    {
        $config = array(
            "digest_alg" => "sha512",
            "private_key_bits" => $bits,           //字节数  512 1024 2048  4096 等
            "private_key_type" => OPENSSL_KEYTYPE_RSA,   //加密类型
        );
        $res = openssl_pkey_new($config);
        if ($res == false) return [];

        openssl_pkey_export($res, $private_key);
        $public_key = openssl_pkey_get_details($res);
        $public_key = $public_key["key"];
        openssl_free_key($res);

        return [$private_key, $public_key];
    }

    /**
     * 生成签名
     * @param array $params 待签名的所有参数
     * @return string 生成的签名
     */
    public static function getSignGenerator($params, $ssl_private)
    {
        //生成待验签的字符串
        $data = self::getSignStr($params);
        $pem = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap($ssl_private, 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";

        //openssl_private_encrypt($data, $crypted, $pem);
        openssl_sign($data, $sign, $pem, OPENSSL_ALGO_SHA256);

        return base64_encode($sign);
    }

    /**
     * 验证签名 公钥验证签名
     * @param array $params 待签名的所有参数
     * @param string $sign 生成的签名
     * @return boolean 校验的结果
     */
    public static function signCheck($encrypted, $sign, $ssl_public)
    {
        //对方的公钥内容 一行的形式
        $pem = "-----BEGIN PUBLIC KEY-----\n" .
            wordwrap($ssl_public, 64, "\n", true) .
            "\n-----END PUBLIC KEY-----";

        $result = @openssl_verify(md5($encrypted), base64_decode($sign), $pem, OPENSSL_ALGO_SHA512);

        return $result == 1;
    }

    /**
     * 我们自己的加密
     * @param $string
     * @param $pubKey
     * @return string
     */
    function encrypt($string, $ssl_public)
    {
        $res = "-----BEGIN PUBLIC KEY-----\n" .
            wordwrap($ssl_public, 64, "\n", true) .
            "\n-----END PUBLIC KEY-----";

        openssl_public_encrypt($string, $encrypt, $res);

        return base64_encode($encrypt);
    }


    /**
     * 私钥加密 (使用公钥解密)
     * @param string $data
     * @param $privateKey
     * @param int $padding
     * @return null|string
     */
    public static function privateEncrypt(string $data, $privateKey, $padding = OPENSSL_PKCS1_PADDING)
    {
        $encrypted = '';
        $chunks = str_split($data, 117);
        foreach ($chunks as $chunk) {
            $partialEncrypted = '';
            $encryptionOk = openssl_private_encrypt($chunk, $partialEncrypted, $privateKey, $padding);
            if ($encryptionOk === false) {
                return null;
            }
            $encrypted .= $partialEncrypted;
        }

        return base64_encode($encrypted);
    }

    /**
     * 公钥加密(使用私钥解密)
     * @param string $data 加密字符串
     * @param int $padding
     * @return null|string
     */
    public static function publicEncrypt(string $data, $publicKey, $padding = OPENSSL_PKCS1_PADDING)
    {
        $encrypted = '';
        $chunks = str_split($data, 117);
        foreach ($chunks as $chunk) {
            $partialEncrypted = '';
            $encryptionOk = openssl_public_encrypt($chunk, $partialEncrypted, $publicKey, $padding);
            if ($encryptionOk === false) {
                return null;
            }
            $encrypted .= $partialEncrypted;
        }

        return base64_encode($encrypted);
    }

    /**
     * @param string $encrypted
     * @param $privateKey
     * @return null
     * @uses 私钥解密 (使用公钥加密)
     */
    public static function privateDecrypt(string $encrypted, $privateKey)
    {
        $decrypted = '';
        $chunks = str_split(base64_decode($encrypted), 128);
        foreach ($chunks as $chunk) {
            $partial = '';
            $decryptIsTrue = openssl_private_decrypt($chunk, $partial, $privateKey);
            if ($decryptIsTrue === false) {
                return null;
            }
//            echo $partial, PHP_EOL;
            $decrypted .= $partial;
        }

        return $decrypted;
    }

    /**
     * 公钥解密 (使用私钥解密)
     * @param string $encrypted 被解密字符串
     * @return null
     */
    public static function publicDecrypt(string $encrypted, $publicKey)
    {
        $decrypted = '';
        $chunks = str_split(base64_decode($encrypted), 128);
        foreach ($chunks as $chunk) {
            $partial = '';
            $decryptIsTrue = openssl_public_decrypt($chunk, $partial, $publicKey);
            if ($decryptIsTrue === false) {
                return null;
            }
            $decrypted .= $partial;
        }
        return $decrypted;
    }

    /**
     * 私钥签名
     * @param $data string 验签内容
     * @param $signature string 签名字符串
     * @param int $signature_alg
     * @return string
     */
    public static function privateSign($data, $privateKey, $signature_alg = OPENSSL_ALGO_SHA1)
    {
        $signature = '';
        openssl_sign($data, $signature, $privateKey, $signature_alg);
        openssl_free_key($privateKey);

        return base64_encode($signature);
    }

    /**
     * 公钥验签
     * @param $data string 验签内容
     * @param $signature string 签名字符串
     * @param int $signature_alg
     * @return bool
     */
    public static function publicSign($data, $signature, $publicKey)
    {
        $result = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA512);

        return $result === 1;
    }

    /**
     * 生成待签名的字符串
     * @param array $data 参与签名的参数数组
     * @return string 待签名的字符串
     */
    public static function getSignStr(array $data)
    {
        unset($data['sign']);
        //排序
        ksort($data);
        //剔除sign 如果对方的签名叫sign 或者可以在调用方法的时候剔除
        //unset($data['sign']);

        $stringToBeSigned = '';

        $i = 0;

        foreach ($data as $k => $v) {
            if ($i == 0) {
                $stringToBeSigned .= "$k" . "=" . "$v";
            } else {
                $stringToBeSigned .= "&" . "$k" . "=" . "$v";
            }

            $i++;
        }

        return $stringToBeSigned;
    }

}

php

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2024年10月17日 09:00
4

目录

来自 《PHP OpenSSL Rsa 工具类》
774 文章数
0 评论量
9 分类数
779 页面数
已在风雨中度过 9年277天3小时37分