php RSA 加密,解密,签名,验签

1.获取公钥,私钥文件,钥匙长度为1024,钥匙格式为PKCS#8

$publicKey = openssl_get_publickey(file_get_contents('publicKey.pem'));
$privateKey = openssl_get_privatekey(file_get_contents('privateKey.pem'));

公钥格式如下:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdPp/QIat8fb+QQldyDiAsswHc
8h6a+MXNZN/0g8Q3kwGEkXIrn2xTo5Zta47NEXDCjEZfm1eo/E60SMY53pzXRipZ
76MRRgKMq8pV6gQB9BpQcHKnZuntFMVVzCWAkKI68+mp++jwjFu6KWU2cXbg/zSs
cR++CpjeEtSagePl3QIDAQAB
-----END PUBLIC KEY-----

私钥格式如下:

-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJ0+n9Ahq3x9v5BC
V3IOICyzAdzyHpr4xc1k3/SDxDeTAYSRciufbFOjlm1rjs0RcMKMRl+bV6j8TrRI
xjnenNdGKlnvoxFGAoyrylXqBAH0GlBwcqdm6e0UxVXMJYCQojrz6an76PCMW7op
ZTZxduD/NKxxH74KmN4S1JqB4+XdAgMBAAECgYBNDUzefkE75ZqjI/8ZopZdkPIO
xI3+vnye4xljBdZ2rRCHV4YsnhhE+9pQj+4PysYIbxhk7QgNhGVEroyD+vO7PMLv
tSdfCeU6TDDqyCVWSctMAUkpDtpbRZ1nd/Nr6f67MB0jur+Q5YjOQ6eQyCpkfHhZ
xnZzfiveApvyuNh5gQJBAMkpUWzXZXTZdW79g7ZR55mDa1qtSAxVGHFYyeuXTsrW
s2DiPClB2hw0brXhLJi7ga04llVAds2ORcpKiLIAF40CQQDIHG+VP8zHCNH4CxZm
AvKM9RKtjpKsxfNcdJbNq+34iX/Vy+oNncOCPEcQLM9KFCejxERq2l49UUkbCasZ
gYuRAkBhpqMWWQGxVZcCSCLWMLBi/z7wB8o/4lc5PsbWjN787HirgWd/B66fnnxX
4nVJt0xeEGg5/k8tvfD3IHN3JUBJAkBv2KTtUImOPXnOH7RXNBKJgnj8FJIai1Fo
PaoELrKFlaSjxKN/FMyvwC0f90us5fL577sl1gOSVhp8SD0ftm5hAkEAq2zxccxs
d1YsYVZucDrJ68JBtxYCXWlzSVszqZRbJy67rNAxRFmb1jLLwqPscQhR2UgXus+b
O71EONcyJvxJ3g==
-----END PRIVATE KEY-----

2.公钥加密(由于1024 bit的钥匙加密的最大长度为117字节,所以将待加密数据按117分割,分断加密之后,连接返加)

/**
 * @param $data 待加密数据
 * @param $publicKey
 * @return string 返回加密后的字符串
 */
function encrytPublicKey($data,$publicKey){
    $encrypt='';
    foreach (str_split($data,117) as $item){
        $temp='';
        openssl_public_encrypt($item,$encrypt,$publicKey);
        $encrypt.=$temp;
    }
    openssl_free_key($publicKey);
    return base64_encode($encrypt);
}

3.私钥解密(待解密字符串长度超过128之后, 按128切割之后分断解密)

/**
 * @param $data 密钥串
 * @param $privateKey
 * @return string  解密之后的字符串
 */
function decryptPrivateKey($data,$privateKey){
    $data = base64_decode($data);
    $decrypt='';
    foreach (str_split($data,128) as $item){
        $temp='';
        openssl_private_decrypt($item,$temp,$privateKey);
        $decrypt.=$temp;
    }
    openssl_free_key($privateKey);
    return $decrypt;
}

4.RSA 私钥生成签名

/**
 * @param $data 待签名字符串
 * @param $privateKey
 * @return string 生成的签名
 */
function generateSign($data,$privateKey){
    $signature='';
    openssl_sign($data,$signature,$privateKey);
    openssl_free_key($privateKey);
    return base64_encode($signature);
}

5.RSA 公钥验签

/**
 * @param $data 待验签数据
 * @param $sign 签名字符串
 * @param $publicKey
 * @return bool
 */
function veritySign($data,$sign,$publicKey){
    $sign=base64_decode($sign);
    $result = openssl_verify($data,$sign,$publicKey);
    openssl_free_key($publicKey);
    return (bool)$result;
}

6.如果公钥和私钥是以字符串的形式提供的, 那么需要将公私钥组成相应的格式(每行64个字符串);

/**
*$data为待加密字符串;
*$key 为公钥字符串
*/
function encode_pay($data, $key)
{	
	$pay_public_key = "-----BEGIN PUBLIC KEY-----\r\n";
	foreach (str_split($key, 64) as $str) {
		$pay_public_key = $pay_public_key . $str . "\r\n";
	}
	$pay_public_key = $pay_public_key . "-----END PUBLIC KEY-----";
	$pu_key = openssl_pkey_get_public($pay_public_key);
	if ($pu_key == false) {
		echo "打开公钥出错";
		die;
	}
	$encryptData = '';
	$crypto = '';
	foreach (str_split($data, 117) as $chunk) {
		openssl_public_encrypt($chunk, $encryptData, $pu_key);
		$crypto = $crypto . $encryptData;
	}
	$crypto = base64_encode($crypto);
	return $crypto;
}

猜你喜欢

转载自blog.csdn.net/pinming_sanlang1990/article/details/81020819