<?php
class Rsa
{
/**
* 生成证书
* @return array
*/
public static function exportOpenSSLFile($bits = 1024)
{
$config = array(
"digest_alg" => "sha512",
"private_key_bits" => $bits, //字节数 512 1024 2048 4096 等
"private_key_type" => OPENSSL_KEYTYPE_RSA, //加密类型
);
$res = openssl_pkey_new($config);
if ($res == false) return [];
openssl_pkey_export($res, $private_key);
$public_key = openssl_pkey_get_details($res);
$public_key = $public_key["key"];
openssl_free_key($res);
return [$private_key, $public_key];
}
/**
* 生成签名
* @param array $params 待签名的所有参数
* @return string 生成的签名
*/
public static function getSignGenerator($params, $ssl_private)
{
//生成待验签的字符串
$data = self::getSignStr($params);
$pem = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($ssl_private, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
//openssl_private_encrypt($data, $crypted, $pem);
openssl_sign($data, $sign, $pem, OPENSSL_ALGO_SHA256);
return base64_encode($sign);
}
/**
* 验证签名 公钥验证签名
* @param array $params 待签名的所有参数
* @param string $sign 生成的签名
* @return boolean 校验的结果
*/
public static function signCheck($encrypted, $sign, $ssl_public)
{
//对方的公钥内容 一行的形式
$pem = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($ssl_public, 64, "\n", true) .
"\n-----END PUBLIC KEY-----";
$result = @openssl_verify(md5($encrypted), base64_decode($sign), $pem, OPENSSL_ALGO_SHA512);
return $result == 1;
}
/**
* 我们自己的加密
* @param $string
* @param $pubKey
* @return string
*/
function encrypt($string, $ssl_public)
{
$res = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($ssl_public, 64, "\n", true) .
"\n-----END PUBLIC KEY-----";
openssl_public_encrypt($string, $encrypt, $res);
return base64_encode($encrypt);
}
/**
* 私钥加密 (使用公钥解密)
* @param string $data
* @param $privateKey
* @param int $padding
* @return null|string
*/
public static function privateEncrypt(string $data, $privateKey, $padding = OPENSSL_PKCS1_PADDING)
{
$encrypted = '';
$chunks = str_split($data, 117);
foreach ($chunks as $chunk) {
$partialEncrypted = '';
$encryptionOk = openssl_private_encrypt($chunk, $partialEncrypted, $privateKey, $padding);
if ($encryptionOk === false) {
return null;
}
$encrypted .= $partialEncrypted;
}
return base64_encode($encrypted);
}
/**
* 公钥加密(使用私钥解密)
* @param string $data 加密字符串
* @param int $padding
* @return null|string
*/
public static function publicEncrypt(string $data, $publicKey, $padding = OPENSSL_PKCS1_PADDING)
{
$encrypted = '';
$chunks = str_split($data, 117);
foreach ($chunks as $chunk) {
$partialEncrypted = '';
$encryptionOk = openssl_public_encrypt($chunk, $partialEncrypted, $publicKey, $padding);
if ($encryptionOk === false) {
return null;
}
$encrypted .= $partialEncrypted;
}
return base64_encode($encrypted);
}
/**
* @param string $encrypted
* @param $privateKey
* @return null
* @uses 私钥解密 (使用公钥加密)
*/
public static function privateDecrypt(string $encrypted, $privateKey)
{
$decrypted = '';
$chunks = str_split(base64_decode($encrypted), 128);
foreach ($chunks as $chunk) {
$partial = '';
$decryptIsTrue = openssl_private_decrypt($chunk, $partial, $privateKey);
if ($decryptIsTrue === false) {
return null;
}
// echo $partial, PHP_EOL;
$decrypted .= $partial;
}
return $decrypted;
}
/**
* 公钥解密 (使用私钥解密)
* @param string $encrypted 被解密字符串
* @return null
*/
public static function publicDecrypt(string $encrypted, $publicKey)
{
$decrypted = '';
$chunks = str_split(base64_decode($encrypted), 128);
foreach ($chunks as $chunk) {
$partial = '';
$decryptIsTrue = openssl_public_decrypt($chunk, $partial, $publicKey);
if ($decryptIsTrue === false) {
return null;
}
$decrypted .= $partial;
}
return $decrypted;
}
/**
* 私钥签名
* @param $data string 验签内容
* @param $signature string 签名字符串
* @param int $signature_alg
* @return string
*/
public static function privateSign($data, $privateKey, $signature_alg = OPENSSL_ALGO_SHA1)
{
$signature = '';
openssl_sign($data, $signature, $privateKey, $signature_alg);
openssl_free_key($privateKey);
return base64_encode($signature);
}
/**
* 公钥验签
* @param $data string 验签内容
* @param $signature string 签名字符串
* @param int $signature_alg
* @return bool
*/
public static function publicSign($data, $signature, $publicKey)
{
$result = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA512);
return $result === 1;
}
/**
* 生成待签名的字符串
* @param array $data 参与签名的参数数组
* @return string 待签名的字符串
*/
public static function getSignStr(array $data)
{
unset($data['sign']);
//排序
ksort($data);
//剔除sign 如果对方的签名叫sign 或者可以在调用方法的时候剔除
//unset($data['sign']);
$stringToBeSigned = '';
$i = 0;
foreach ($data as $k => $v) {
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . "$v";
} else {
$stringToBeSigned .= "&" . "$k" . "=" . "$v";
}
$i++;
}
return $stringToBeSigned;
}
}
版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。