对接某平台时,要求使用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代码:
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);
记一次RSA公钥加密失败的问题情景再现对接某平台时,要求使用RSA加密消息传输,提供的公钥如下:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDuduPhifW7Mp5K80tVHS-R-lOD_OO5u2ZVNRELJlfiwF8hdKr1zt5VJ_IfWdx990Qrln2InN_Aym0phg5SVw2hDrwMTeQBOPsFXv-Ts0tcbnr4...
警告:使用风险自负。 未经广泛测试或审查。 可能包含严重的错误。
另请参阅: 。 为rust-openssl编写的示例代码:
let mut shared_e = vec! [ 0 ; rsa. size () as usize ];
let mut token_e = vec! [ 0 ; rsa. size () as usize ];
rsa. public_encrypt ( & shared, & mut shared_e, Padding :: PKCS1)?;
rsa. public_encrypt ( & packet.verify_token.da
本地PHP 7.0.8,一下代码运行OK
function getAuthorizedUrl($base_url, $encrypted_params, $non_encrypted_params = [])
$appId = '1111';
$pid = '111111';
$public_key = "-----BEGIN PUBLIC KEY-----\nMy p...
以下是使用OpenSSL的RSA_public_encrypt函数进行分段加密的一个示例代码:#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <assert.h>// 加密函数,用公钥加密
int public_encrypt(unsigned char* data, int data_len, unsigned char* key, unsigned char* encrypted)
// 公钥
RSA * rsa = createRSA(key, 1);
// 加密后的长度
int length = RSA_size(rsa);
// 分段加密
int offset = 0;
int inputLen = data_len;
while (inputLen > 0)
// 计算本次加密长度
int encryptLen = inputLen > length - 11 ? length - 11 : inputLen;
int ret = RSA_public_encrypt(encryptLen, data + offset, encrypted + offset, rsa, RSA_PKCS1_PADDING);
// 加密出错
if (ret < 0)
return ret;
offset += ret;
inputLen -= encryptLen;
return offset;
}// 生成RSA公钥
RSA * createRSA(unsigned char* key, int isPublic)
// 将公钥文本转换为BIO类型
BIO* bio = BIO_new_mem_buf(key, -1);
// 从BIO类型中读取公钥
RSA* rsa = NULL;
if(isPublic)
rsa = PEM_read_bio_RSA_PUBKEY(bio, &rsa, NULL, NULL);
rsa = PEM_read_bio_RSAPrivateKey(bio, &rsa, NULL, NULL);
// 释放BIO类型
BIO_free_all(bio);
return rsa;