php RSA加密 openssl_public_encrypt(): key parameter is not a valid public key

记一次RSA公钥加密失败的问题

情景再现

对接某平台时,要求使用RSA加密消息传输,提供的公钥如下:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDuduPhifW7Mp5K80tVHS-R-lOD_OO5u2ZVNRELJlfiwF8hdKr1zt5VJ_IfWdx990Qrln2InN_Aym0phg5SVw2hDrwMTeQBOPsFXv-Ts0tcbnr4UpCsBR37N4ZXfJrKXcNihWBYdfFGj0EchiMJmdQawIHf–d1HQxt2fSojoOARwIDAQAB

使用这个公钥加密之后报错了,返回

openssl_public_encrypt(): key parameter is not a valid public key

发现 openssl_pkey_get_public($publicKey); 返回 false。

注: 我已添加 :$public_key = “-----BEGIN PUBLIC KEY-----\n” . $public_key . “\n-----END PUBLIC KEY-----”;

搜了一天的资料,也没有找到这种问题的相关内容。

之后对方提供了JAVA的示例代码,在查询代码时发现有一处

> String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());

查阅资料发现这个encodeBase64URLSafeString是为了防止在url传输base64的时候不能正确传递base64所作出的转义。

转义代码如下:

public static function url_safe_decode($string)
{
    $data = str_replace(['-','_'], ['+','/'], $string);
    $mod4 = strlen($data) % 4;
    if ($mod4)
    {
        $data .= substr('====', $mod4);
    }
    return $data;
}

public static function url_safe_encode($string)
{
    return str_replace(['+','/','='], ['-','_',''], $string);
}

到这终于知道了,原来对方给的公钥是经过转义之后的公钥,对方也没说明公钥被他转义过了,我找过去的时候还说公钥没有问题,在这上面耗费了挺长时间的。

解决

$str = '123456';
$public_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDuduPhifW7Mp5K80tVHS-R-lOD_OO5u2ZVNRELJlfiwF8hdKr1zt5VJ_IfWdx990Qrln2InN_Aym0phg5SVw2hDrwMTeQBOPsFXv-Ts0tcbnr4UpCsBR37N4ZXfJrKXcNihWBYdfFGj0EchiMJmdQawIHf--d1HQxt2fSojoOARwIDAQAB';
$public_key = RsaUtil::url_safe_decode($public_key);
$public_key = "-----BEGIN PUBLIC KEY-----\n" . $public_key . "\n-----END PUBLIC KEY-----";
$encrypted = RsaUtil::publicEncrypt($str, $public_key);

下面贴出完整RsaUtil代码:

<?php
namespace App\Helpers;


class RsaUtil
{
    private static function getPublicKey($publicKey)
    {
        return openssl_pkey_get_public($publicKey);
    }

    private static function getPrivateKey($privateKey)
    {
        return openssl_pkey_get_private($privateKey);
    }

    public static function publicEncrypt($data, $publicKey)
    {
        if (!is_string($data)) {
            return null;
        }
        return openssl_public_encrypt($data, $encrypted, self::getPublicKey($publicKey)) ? base64_encode($encrypted) : null;
    }

    public static function publicDecrypt($encrypted, $publicKey)
    {
        if (!is_string($encrypted)) {
            return null;
        }
        return (openssl_public_decrypt(base64_decode($encrypted), $decrypted, self::getPublicKey($publicKey))) ? $decrypted : null;
    }

    public static function privateEncrypt($data, $privateKey)
    {
        if(!is_string($data)){
            return null;
        }
        return openssl_private_encrypt($data, $encrypted, self::getPrivateKey($privateKey)) ? base64_encode($encrypted) : null;
    }

    public static function privateDecrypt($encrypted, $privateKey)
    {
        if(!is_string($encrypted)){
            return null;
        }
        return (openssl_private_decrypt(base64_decode($encrypted), $decrypted, self::getPrivateKey($privateKey)))? $decrypted : null;
    }

    /**
     * @param $string
     * @return string|string[]
     * url安全解码
     */
    public static function url_safe_decode($string)
    {
        $data = str_replace(['-','_'], ['+','/'], $string);
        $mod4 = strlen($data) % 4;
        if ($mod4)
        {
            $data .= substr('====', $mod4);
        }
        return $data;
    }

    /**
     * @param $string
     * @return string|string[]
     * url安全转码
     */
    public static function url_safe_encode($string)
    {
        return str_replace(['+','/','='], ['-','_',''], $string);
    }
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值