代码phpphp使用rsa进行公钥解密
Alon问题
最近对接一个三方的通道,对方给了一个java的rsa公钥解密的demo。我想当然直接用php的openssl_public_decrypt一顿操作,出来个null。WTF?
贴一下java的demo如下
package com.test;
import cn.hutool.core.codec.Base64; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.URLUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA;
import java.nio.charset.Charset;
public class VerifyRsaTest {
public static void main(String[] args) throws Exception {
String publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyxVgchYx/xx3jWyKPxb4s7boVOSDLxu7MP2U0NNAqtWSNMRRF+5sAjMd3RyeftsRT/QWAf2Rs9P/oZikGP0yqpsrWYHgbLcYLqIsgNPr6yOk855gvHB5szRsQggK0d4hl562Lx5T9DvHuM5u2jChsqZ7PvRXmNa+SDBtEB/3fnwIDAQAB"; String aa="C5rKZS/HWcEcaSFVyjmmOThYeEaEUwzK7kJf9NK5MkzkWxFH7VoQJS77c19jm9mt1YlhL5RGIficRi2W2+O8yMsT1Jps/7zvtzgV3lMp4ZBWciRg7/UU5CJq/CrVtfxHYrNQKn5eFTpaDX/cENb8u47vxtjZpwPhbNIc7HSCCLVZ0qSUgKCFHS/JNMGnin8rpCOL0ON5nEzmJnyDhlQikTVDTgDYdDyGokOkGnIUrD9JcMQ0sSLQXRk3qT3zfCAamgRWhDUDgUG+7HHoya5nFwjJ+UHq7pfxcu+gFDDWvHqAN1q+ayl1kb7hf0NSYjG0/d/MB2LT5XLxhDgVIQSwGiHRB/1nHIiNJGQnEirtsNcGSl9hXZ7PPaAm5Oo2gadIFh8ro0BKwnlmha6WmRS47sf7De3zlRVeSLWYXJYyniFj9+LumdUOgwWaZHrJXSpQSTj2GQtwLy0yjirkWKJXt2YfpeEXsUpaZib0Rbo8yuruvZqM1aAKtMwGRdBwTvKXECA6uCqizBPBtyNRRAUL7AvwZCKHJQdAY1u4yhKngDYEwO651PPVO/IkKw9CbC4mRpfhD5sIFoqIcFyl0f4ns/USip5gKUofKGv0hStQD8Hq9JIQEvR9M5lkx2KZarudIttZiZKycqMUA4xCHsJetbohBDQwMHY3I0tsKjy3WuiWbzJsuJrQD4qfbp72UOKjD+zdeyTzykdKOPEYvmsEucSlubFrd8jmQlyWjR/3roQCqlhGlZmH7CGf+epSewULOjQP6geUh1Zl2p0CJNBNd8olCqIHFt4AQqb1GhdVLcDpOg63HBGj8O+WiLbM9sE7umDYizmC7ImNIQ0mPRPuBw==";
String str = URLUtil.decode(aa, Charset.defaultCharset(),false);
String decrypt = decryptRsaPublicKey(str, publicKey); System.out.println("对接方解密,decrypt = " + decrypt);
}
public static String decryptRsaPublicKey(String targetData, String publicKeyBase64) { RSA rsa = SecureUtil.rsa(null, publicKeyBase64); byte[] decrypt = rsa.decrypt(Base64.decode(targetData), KeyType.PublicKey); return new String(decrypt, CharsetUtil.CHARSET_UTF_8); } }
|
再贴一下一开始的php尝试如下
$publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyxVgchYx/xx3jWyKPxb4s7boVOSDLxu7MP2U0NNAqtWSNMRRF+5sAjMd3RyeftsRT/QWAf2Rs9P/oZikGP0yqpsrWYHgbLcYLqIsgNPr6yOk855gvHB5szRsQggK0d4hl562Lx5T9DvHuM5u2jChsqZ7PvRXmNa+SDBtEB/3fnwIDAQAB"; $txt="C5rKZS/HWcEcaSFVyjmmOThYeEaEUwzK7kJf9NK5MkzkWxFH7VoQJS77c19jm9mt1YlhL5RGIficRi2W2+O8yMsT1Jps/7zvtzgV3lMp4ZBWciRg7/UU5CJq/CrVtfxHYrNQKn5eFTpaDX/cENb8u47vxtjZpwPhbNIc7HSCCLVZ0qSUgKCFHS/JNMGnin8rpCOL0ON5nEzmJnyDhlQikTVDTgDYdDyGokOkGnIUrD9JcMQ0sSLQXRk3qT3zfCAamgRWhDUDgUG+7HHoya5nFwjJ+UHq7pfxcu+gFDDWvHqAN1q+ayl1kb7hf0NSYjG0/d/MB2LT5XLxhDgVIQSwGiHRB/1nHIiNJGQnEirtsNcGSl9hXZ7PPaAm5Oo2gadIFh8ro0BKwnlmha6WmRS47sf7De3zlRVeSLWYXJYyniFj9+LumdUOgwWaZHrJXSpQSTj2GQtwLy0yjirkWKJXt2YfpeEXsUpaZib0Rbo8yuruvZqM1aAKtMwGRdBwTvKXECA6uCqizBPBtyNRRAUL7AvwZCKHJQdAY1u4yhKngDYEwO651PPVO/IkKw9CbC4mRpfhD5sIFoqIcFyl0f4ns/USip5gKUofKGv0hStQD8Hq9JIQEvR9M5lkx2KZarudIttZiZKycqMUA4xCHsJetbohBDQwMHY3I0tsKjy3WuiWbzJsuJrQD4qfbp72UOKjD+zdeyTzykdKOPEYvmsEucSlubFrd8jmQlyWjR/3roQCqlhGlZmH7CGf+epSewULOjQP6geUh1Zl2p0CJNBNd8olCqIHFt4AQqb1GhdVLcDpOg63HBGj8O+WiLbM9sE7umDYizmC7ImNIQ0mPRPuBw==";
$publicKey = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($publicKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----"; $publicKeyResource = openssl_pkey_get_public($publicKey); openssl_public_decrypt(base64_decode($txt), $decryptedData, $publicKeyResource); dd($decryptedData);
|
解决
然后开始google,百度一顿搜,搜出来的不能说一点用没有吧,也可以说是啥忙也帮不上了。于是learnku求助了一下社区的大佬们,得到了解答,特此记录一下。
原因
rsa加密和解密根据秘钥长度不同,对密文长度是有限制的。
秘钥对应密文长度
秘钥长度 |
加密最大长度 |
解密最大长度 |
1024 |
117 |
128 |
2048 |
245 |
256 |
4096 |
501 |
512 |
解决开始对应的java demo转译php
function decryptRsaPublicKey($targetData, $publicKeyBase64) { $publicKey = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($publicKeyBase64, 64, "\n") . '-----END PUBLIC KEY-----';
$decodedData = base64_decode($targetData);
$keyResource = openssl_pkey_get_public($publicKey); if (!$keyResource) { throw new Exception('Invalid public key'); }
$decrypted = ''; $maxLength = 128; $offset = 0;
while ($offset < strlen($decodedData)) { $chunk = substr($decodedData, $offset, $maxLength); $offset += $maxLength; $decryptedChunk = '';
if (!openssl_public_decrypt($chunk, $decryptedChunk, $keyResource)) { throw new Exception('Failed to decrypt data'); } $decrypted .= $decryptedChunk; }
openssl_free_key($keyResource);
return $decrypted; }
$publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyxVgchYx/xx3jWyKPxb4s7boVOSDLxu7MP2U0NNAqtWSNMRRF+5sAjMd3RyeftsRT/QWAf2Rs9P/oZikGP0yqpsrWYHgbLcYLqIsgNPr6yOk855gvHB5szRsQggK0d4hl562Lx5T9DvHuM5u2jChsqZ7PvRXmNa+SDBtEB/3fnwIDAQAB'; $txt = 'C5rKZS/HWcEcaSFVyjmmOThYeEaEUwzK7kJf9NK5MkzkWxFH7VoQJS77c19jm9mt1YlhL5RGIficRi2W2+O8yMsT1Jps/7zvtzgV3lMp4ZBWciRg7/UU5CJq/CrVtfxHYrNQKn5eFTpaDX/cENb8u47vxtjZpwPhbNIc7HSCCLVZ0qSUgKCFHS/JNMGnin8rpCOL0ON5nEzmJnyDhlQikTVDTgDYdDyGokOkGnIUrD9JcMQ0sSLQXRk3qT3zfCAamgRWhDUDgUG+7HHoya5nFwjJ+UHq7pfxcu+gFDDWvHqAN1q+ayl1kb7hf0NSYjG0/d/MB2LT5XLxhDgVIQSwGiHRB/1nHIiNJGQnEirtsNcGSl9hXZ7PPaAm5Oo2gadIFh8ro0BKwnlmha6WmRS47sf7De3zlRVeSLWYXJYyniFj9+LumdUOgwWaZHrJXSpQSTj2GQtwLy0yjirkWKJXt2YfpeEXsUpaZib0Rbo8yuruvZqM1aAKtMwGRdBwTvKXECA6uCqizBPBtyNRRAUL7AvwZCKHJQdAY1u4yhKngDYEwO651PPVO/IkKw9CbC4mRpfhD5sIFoqIcFyl0f4ns/USip5gKUofKGv0hStQD8Hq9JIQEvR9M5lkx2KZarudIttZiZKycqMUA4xCHsJetbohBDQwMHY3I0tsKjy3WuiWbzJsuJrQD4qfbp72UOKjD+zdeyTzykdKOPEYvmsEucSlubFrd8jmQlyWjR/3roQCqlhGlZmH7CGf+epSewULOjQP6geUh1Zl2p0CJNBNd8olCqIHFt4AQqb1GhdVLcDpOg63HBGj8O+WiLbM9sE7umDYizmC7ImNIQ0mPRPuBw==';
$d = decryptRsaPublicKey($txt, $publicKey);
var_dump($d);
|