wechatpay-apiv3 / wechatpay-guzzle-middleware

微信支付 APIv3 Guzzle HTTP Client中间件(middleware)
Apache License 2.0
208 stars 46 forks source link

SensitiveInfoCrypto 这个类过度设计了,看起来简单,其实并不简单 #25

Open ifreesec opened 4 years ago

ifreesec commented 4 years ago

另外传进去的证书也不一定要是 resource 啊,放缓存里也是可以的吧

xy-peng commented 4 years ago

@TheNorthMemory

@ifreesec 有什么建议吗,另外也欢迎PR。

tpirc3 commented 4 years ago

传入的$publicCert参数类型为resource其实本意是指使用PemUtil::loadCertificate或者openssl_x509_read返回的EVP_PKEY resource,而不是要从文件读取的resource。 如果证书放缓存里,可以借助PemUtil::loadCertificateFromString实现,这样使用 $encryptor = new SensitiveInfoCrypto(PemUtil::loadCertificateFromString('缓存的证书'));

ifreesec commented 4 years ago

传入的$publicCert参数类型为resource其实本意是指使用PemUtil::loadCertificate或者openssl_x509_read返回的EVP_PKEY resource,而不是要从文件读取的resource。 如果证书放缓存里,可以借助PemUtil::loadCertificateFromString实现,这样使用 $encryptor = new SensitiveInfoCrypto(PemUtil::loadCertificateFromString('缓存的证书'));

这个理解了,感谢

ifreesec commented 4 years ago

@TheNorthMemory

@ifreesec 有什么建议吗,另外也欢迎PR。

我的想法很简单,就是按正常的方法去使用加密和解密,正常的拆分成两个类

//加密
class SensitiveInfoEncrypt
{
    /**
     * string 的话可以 PemUtil::loadCertificateFromString 处理下在传入
     *
     * @var resource|null $publicCert The public certificate
     */
    private $publicCert;

    /**
     * SensitiveInfoEncrypt constructor.
     * @param null $publicCert 微信支付平台证书
     */
    public function __construct($publicCert)
    {
        $this->publicCert = $publicCert;
    }

    /**
     * @param $str
     * @return string
     */
    public function encrypt($str)
    {
        if (!is_resource($this->publicCert)) {
            throw new \InvalidArgumentException('The publicCert must be resource.');
        }
        openssl_public_encrypt($str, $encrypted,
            $this->publicCert, \OPENSSL_PKCS1_OAEP_PADDING);

        return \base64_encode($encrypted);
    }
}

//解密
class SensitiveInfoDecrypt
{
    /**
     * @var resource|null $privateKey The private key
     */
    private $privateKey;

    /**
     * SensitiveInfoDecrypt constructor.
     * @param null $privateKey 微信商户私钥
     */
    public function __construct($privateKey = null)
    {
        $this->privateKey = $privateKey;
    }

    /**
     * 解密
     * @param $str
     * @return string
     */
    public function decrypt($str)
    {
        if (!is_resource($this->privateKey)) {
            throw new \InvalidArgumentException('The privateKey must be resource.');
        }
        openssl_private_decrypt(\base64_decode($str), $decrypted,
            $this->privateKey, \OPENSSL_PKCS1_OAEP_PADDING);

        return $decrypted;
    }
}

@xy-peng

TheNorthMemory commented 4 years ago

刚看到提醒,抱歉。 楼主批评得对,这用法上基本都是单一场景,要么加密,要么解密,俩揉在一起是有点过度设计了,而且容易造成干扰。。。

TheNorthMemory commented 3 years ago

新包设计上,加/解密用法是:

环境要求 ^PHP7.2.5 || ^8.0 -> https://github.com/wechatpay-apiv3/wechatpay-php