php与java关于RSA加密解密的实践

本文介绍了在PHP中实现RSA加密解密的过程,特别是如何将JAVA的16进制公钥转换为PEM格式,并详细讲解了PHP中RSA加密的注意事项,包括数据填充方式和明文长度限制。此外,还提供了JAVA RSA实现的代码参考,强调了掌握多种语言对于理解技术底层的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于最近公司与第三方平台要做兑换券的销售,于是需要写接口对接,对方文档写到,需要通过RSA非对称加密,对兑换码进行加密再传输,然而对方并没有SDK提供,提供了个JAVA的类,但是我们平台是使用php开发web,没办法,只能自己研究,当然也从这个过程中学到不少东西,特此记录一些关键点。

公钥私钥的格式

关于RSA加密的原理,可以自己搜索,RSA只能用于加密一些长度不长的数据。当然也有补充方案,就是分段加密。

查看了对方java代码,可以知道是 X.509 证书资源,然后一般平台给出去的公钥是16进制字符串,php关于RSA加密、解密的函数 openssl_pkey_get_public 可以解密的证书:

  1. 一个 X.509 证书资源
  2. 一个file://path/to/file.pem格式的字符串。文件名必须包含一个PEM编码的证书或者密钥(也许二者都有).
  3. 一个 PEM 格式的公钥。

所以首先我们需要将对方给的16进制数转为PEM格式的公钥内容。下面是一个公钥的示例:

-----BEGIN PUBLIC KEY-----  
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3//sR2tXw0wrC2DySx8vNGlqt  
3Y7ldU9+LBLI6e1KS5lfc5jlTGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2kl  
Bd6h4wrbbHA2XE1sq21ykja/Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o  
2n1vP1D+tD3amHsK7QIDAQAB  
-----END PUBLIC KEY-----

PEM格式的公钥有开头和结尾的两个标示,然后每64位进行换行

php 转换十六进制公钥:

// 将十六进制,转换回普通字符串
$publicStr = base64_encode(hex2bin($public_key));
// 每64位进行换行
$key = (wordwrap($publicStr, 64, "\n", true))."\n";
// 添加pem格式头和尾
$pem_key = "-----BEGIN PUBLIC KEY-----\n" . $key . "-----END PUBLIC KEY-----\n";

这样,我们就得到了正常PEM证书中的字符串格式

RSA加密和解密

// public key encrypt
public function encryptByPublicKey($data, $public_key)
{
	// 从证书中得到资源
	$publicKeyPEM = openssl_pkey_get_public($public_key);
	// 加密
	$result = openssl_public_encrypt($data, $encrypted, $publicKeyPEM, OPENSSL_PKCS1_PADDING); 
	// 返回数据
	return $result ? base64_encode($encrypted) : false;
}

public function decryptByPublicKey($data, $public_key)
{
	// 从证书中得到资源
	$publicKeyPEM = openssl_pkey_get_public($public_key);
	// 解密
	$result = openssl_public_decrypt(base64_decode($data), $decrypted, $publicKeyPEM, OPENSSL_PKCS1_PADDING);
	// 返回数据
	return $result ? $decrypted : false;
}

私钥同理,我们项目只用到了公钥

  1. 加密后需要进行 base64_encode,因为加密后的数据直接输出是乱码,保证数据传输过程中不会丢失和出错
  2. OPENSSL_PKCS1_PADDING 其实可以不写,是函数的默认值,这个是数据的填充方式,还有其他的值,这个需要询问对方使用的方式,一般默认这个,可以查看php文档:openssl_public_encrypt
  3. 这里没有进行明文长度的限制,因为我们加密的东西是定长12位字符串,不会存在超过117字节的情况,如果你不是,需要分段加密,可以参考php文档官方的例子:
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值