/*签名生成
(1)生成原始RSA私钥文件rsa_private_key.pem
openssl genrsa -out rsa_private_key.pem 1024
(2)将原始的RSA私钥转换为pkcs8模式
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
(3)生成RSA公钥 rsa_public_key.pem
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
注:php中使用openssl方法,签名和验签,不需要第三步,Java的私钥需要做第三步(java要求PKCS8格式的私钥,php的话PKCS1格式和PKCS8格式均可。PKCS1格式开头是:BEGIN RSA PRIVATE KEY。而PKCS8格式开头是:BEGIN RSA PRIVATE KEY。这是一个小细节。为了避免语言互通有麻烦,用PKCS8格式即可)。
*/
/*
也可以用生成公钥私钥对的网址,直接点击生成即可
生成:http://web.chacuo.net/netrsakeypair
检测是否配对:http://tool.chacuo.net/cryptrsakeyvalid
*/
#签名处理,先把空格换行符都去掉,如果是上边网站生成的,则无需处理
/*$pem = chunk_split($public_key,64,"\n");//转换为pem格式的公钥
$pem = "-----BEGIN PUBLIC KEY-----\n" . $content . "-----END PUBLIC KEY-----\n";*/
/**
* 格式化公钥
*/
function formatPubKey($public_key)
{
$public_key = chunk_split($public_key,64,"\n");
$public_key = "-----BEGIN PUBLIC KEY-----\n" . $public_key . "-----END PUBLIC KEY-----\n";
echo $public_key;
}
/**
* 格式化私钥
*/
function formatPriKey($private_key)
{
$private_key = chunk_split($private_key,64,"\n");
$private_key = "-----BEGIN PRIVATE KEY-----\n" . $private_key . "-----END PRIVATE KEY-----\n";
echo $private_key;
}
//感觉私钥公钥可以传字符串也可以传资源类型
/**
* 签名字符串,私钥签名
* @param $prestr 需要签名的字符串
* return 签名结果
*/
function rsaSign($prestr) {
$public_key= file_get_contents('rsa_private_key.pem');
$pkeyid = openssl_get_privatekey($public_key);
//openssl_sign($msg, $sign, $ key, OPENSSL_ALGO_SHA1);
openssl_sign($prestr, $sign, $pkeyid);
openssl_free_key($pkeyid);
$sign = urlsafe_b64encode($sign);//会有些特殊字符'+','/','='直接拼接到url里面,会被替换或者忽略
return $sign;
}
//$verify = openssl_verify($prestr, urlsafe_b64decode($sign), $public_key);
/**
* 验证签名,公钥验签
* @param $prestr 需要签名的字符串
* @param $sign 签名结果
* return 签名结果
*/
function rsaVerify($prestr, $sign) {
$sign = urlsafe_b64decode($sign);
$public_key= file_get_contents('rsa_public_key.pem');
$pkeyid = openssl_get_publickey($public_key);
if ($pkeyid) {
$verify = openssl_verify($prestr, $sign, $pkeyid);
openssl_free_key($pkeyid);
}
if($verify == 1){
return true;
}else{
return false;
}
}
/**
* RSA公钥加密,urlsafe_b64encode
* @param string $key: 公钥
* @param string $srcStr: 待加密字符串
* @return string 密文
*/
function rsaPubSafeEncrypt($key, $srcStr){
$sign = '';
$res = openssl_pkey_get_public($key);
if ($res) {
openssl_public_encrypt($srcStr, $sign, $res);
openssl_free_key($res);
$sign = urlsafe_b64encode($sign);
}
return $sign ? $sign : '';
}
/**
* RSA公钥加密,base64_encode
* @param string $signStr: 待加密字符串
* @param string $appPubKey: 公钥
* @return string 密文
*/
function rsaPubEncrypt($signStr, $appPubKey){
$encrypt = '';
$pkeyid = openssl_get_publickey($appPubKey);
if(openssl_public_encrypt($signStr, $encryptedTemp, $pkeyid)) {
openssl_free_key($pkeyid);
$encrypt = base64_encode($encryptedTemp);
}
return $encrypt ? $encrypt : '';
}
/**
* RSA分段公钥加密
* 如果待加密字符串长度超过117,则需要分段加密
* @param string $key: 公钥
* @param string $srcStr: 待加密字符串
* @return string 密文
*/
function rsaPubSplitEncrypt($key, $srcStr){
$encrypt = '';
$pkeyid = openssl_pkey_get_public($key);
$dataArray = str_split($srcStr, 100);// 100
if ($pkeyid) {
foreach ($dataArray as $value) {
$encryptedTemp = "";
openssl_public_encrypt($value, $encryptedTemp, $pkeyid);//公钥加密
$encrypt .= $encryptedTemp;
}
openssl_free_key($pkeyid);
$encrypt = base64_encode($encrypt);
}
return $encrypt ? $encrypt : '';
}
/**
* RSA分段私钥解密
* @param string $key: 私钥
* @param string $encryptData: 待解密字符串
* @return string 明文
*/
function rsaPriSplitDecrypt($key, $encryptData)
{
$decrypted = '';
$pi_key = openssl_pkey_get_private($key);
if($pi_key){
$data = str_split(base64_decode($encryptData), 128);// 128
foreach ($data as $chunk){
$partial = '';
openssl_private_decrypt($chunk, $partial, $pi_key);
$decrypted .= $partial;
}
}
return $decrypted ? $decrypted : '';
}
//一行也行openssl_public_decrypt(base64_decode($eccryptData), $decrypted, $publicKey);//公钥解密
/**
* RSA公钥解密
* @param string $eccryptData: 待解密字符串
* @param string $publicKey: 公钥
* @return string 解密后字符串
*/
function pubDecrypt($eccryptData, $publicKey)
{
$decrypted = "";
$decodeStr = base64_decode($eccryptData);//如果是urlsafe_b64decode则这里改下
openssl_public_decrypt($decodeStr, $decrypted, $publicKey);
return $decrypted ? $decrypted : '';
}
/**
* RSA私钥加密,base64_encode
* @param string $signStr: 待加密字符串
* @param string $appPriKey: 私钥
* @return string 密文
*/
function rsaPriEncrypt($signStr, $appPriKey){
$encrypt = '';
$pkeyid = openssl_get_privatekey($appPriKey);
if(openssl_private_encrypt($signStr, $encryptedTemp, $pkeyid)) {
openssl_free_key($pkeyid);
$encrypt = base64_encode($encryptedTemp);
}
return $encrypt ? $encrypt : '';
}
//一行也行openssl_private_decrypt(base64_decode($eccryptData), $decrypted, $prikey);//私钥解密
/**
* RSA私钥解密
* @param string $eccryptData: 待解密字符串
* @param string $decryptKey: 私钥
* @return string 解密后字符串
*/
function priDecrypt($eccryptData, $decryptKey)
{
$decrypted = "";
$decodeStr = base64_decode($eccryptData);//如果是urlsafe_b64decode则这里改下
openssl_private_decrypt($decodeStr, $decrypted, $decryptKey);
return $decrypted ? $decrypted : '';
}
function urlsafe_b64encode($string) {
$data = base64_encode($string);
$data = str_replace(array('+','/','='),array('-','_',''),$data);
return $data;
}
function urlsafe_b64decode($string) {
$data = str_replace(array('-','_'),array('+','/'),$string);
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr('====', $mod4);
}
return base64_decode($data);
}