PHP RSA加密解密连接java

来源:互联网 发布:彩虹易支付源码 编辑:程序博客网 时间:2024/05/23 18:42

最近项目有个接口要通过RSA非对称加密方式获取数据,查了好多资料,搞了我3天,终于出来了,记录下,以便日后遇到可以翻来看看

RSA非堆成加密用的是公钥和私钥对加密解密,公钥加密,私钥解密,也可以私钥加密,公钥解密。

话不多说,直接上代码

//这里是需要加密的字符串,加密方法不支持数组,要转成json格式的字符串

$string='{"phone":"18057130159","token":"858aae0e40db4ce0a35341e493a52b8c","userKey":"10214465165180000668913","deviceId":"5c26cd04e506b9117f6a2c452e35bcae"}';
//$str = '{"phone":"18057130159"}';

首先要用openssl生成公钥私钥对

$publicKey = file_get_contents('rsa_public_key.pem');
$privateKey = file_get_contents('rsa_private_key.pem');

公钥格式

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNDldGnSIyidm/u826q1RKEysp
jQOPrHiBmQn6HMBDMZkT7LZnV7II4Cp8HNhpsU+xVVZ5yBAYchqzXAO131yzoJDJ
rEqynzaAVdUm8sKAwjwrWtdV8K+DNZf3TyrUFDnGFG26lkQ8zmb2bCo7VdhPL5NI
GhBLFHWNyksjyPdaCwIDAQAB
-----END PUBLIC KEY-----

私钥格式

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDNDldGnSIyidm/u826q1RKEyspjQOPrHiBmQn6HMBDMZkT7LZn
V7II4Cp8HNhpsU+xVVZ5yBAYchqzXAO131yzoJDJrEqynzaAVdUm8sKAwjwrWtdV
8K+DNZf3TyrUFDnGFG26lkQ8zmb2bCo7VdhPL5NIGhBLFHWNyksjyPdaCwIDAQAB
AoGAKY+Fiu9gNgQQmTbUTMha7iSSc/p7xUv8pK/DAOmA4l2UHCC3G5z/naLpmXwz
NMDWWSflvgsZkArYdI/qxJr/6587Sy7XYkESRoU8uYAEcccBqGRUMZKFX4pw2v5a
Q2K+NsLMJIfi06SAMM3T1gi6rbL7X0aoGz4O3hkMkZvccdkCQQD2JGAuowNLERa8
9rHL0uAKAXv1MAWK7mtYcPJ9o7P9kWosH1nflZybJTj9zeWuQZeWM6JlYo8MjNJM
0W6Vj5xXAkEA1US4swKmgyRmHkBArWczLxNwKdbD9mDJPBAnKJPyX5ftzU6QbrEG
UfsUhjovmW3GCnvqWtJay/MPQEp1Ji7fbQJBAObJ2qk/zZGwFzrcsH6lXc3j8F9I
RJoszNfjJ2soeFaT5xIx3ynl9S3/K73GNco61DBQf79CN1CUJYdDg8WWHwcCQBAh
g4rer3OJ5ENzfrDe9msgIEK54NaY2X+2hQ+3qQR7/FukDp6guyamRBYm/oSvXeRb
HQ3DjWSRvNyTBStfLj0CQEyVHxdXO2R6VqQbkSO2u73SAJc/WrUrR2oFZyw2LJjz
eirfuSFLY0EmZy14ulogeC1FtzTMKfsjAAKnHvbjKB8=
-----END RSA PRIVATE KEY-----


公钥和私钥的格式一定要严格按照上面的来,不然不能用

//先来验证公钥和私钥是否可用

openssl_pkey_get_private($privateKey);

openssl_pkey_get_public($publicKey);

//可用返回的是资源,resource,不可用返回fasle

RSA非对称加密支持的最大字节是公钥的模长-11

好像是明文在32位字符都可以直接加密,大于32的要分组,没去仔细测试,直接说分组加密的问题

//公钥加密

$data = '';
for($i=0;$i<strlen($string);$i++){
openssl_public_encrypt(substr($string,$i*16,16),$encrypt,($publicKey));
$data .= $encrypt;
//$data .= ":::";
}

$datas = '';
//$encrypted = explode(":::",$data);
//var_dump($encrypted[0]);

//私钥解密  这里是自己生成的,要根据128分组,我项目中用到的java那边生成的公钥长度是128字符,是根据64分组,搞了两天都是不知道根据哪里分组,后来直接循环把所

//有的都打印出来了,看从哪里开始可以解密成功,就从哪里分组了
for($i=0;$i<strlen($data);$i++){
openssl_private_decrypt(substr($data,$i*128,128),$decrypt,($privateKey));
$datas .= $decrypt;
}

$datas2 = '';

//私钥加密
for($i=0;$i<strlen($datas);$i++){
openssl_private_encrypt(substr($datas,$i*16,16),$encrypted2,$privateKey);
$datas2 .= $encrypted2;
}
$decrypted2 = '';

//公钥解密
for($i=0;$i<strlen($datas2);$i++){
openssl_public_decrypt(substr($datas2,$i*128,128),$decrypted,$publicKey);
$decrypted2 .= $decrypted;
}
echo "原文是:".$string;
var_dump( "公钥加密结果是:".$data);
var_dump("私钥解密结果是:".$datas) ;
var_dump("私钥加密结果是:".$datas2);
var_dump("公钥解密结果是:".$decrypted2);

0 0