最近公司业务需要用到私钥和公钥。 我以前和他们接触很少,对他们了解不多。 我只是上网了解他们。 我发现很多地方都使用了加密。 有对称加密算法(DES、AES)[加密和解密]都使用密钥]和非对称加密算法(RSA)。 我们这里所说的是RSA(非对称加密算法)。
在这里写下图片描述
在这里写下图片描述
你需要记住的是:私钥加密,公钥泄露。 公钥加密,私钥泄露。 RSA 加密:##
SHA-1(杀一)中RSA算法的核心特点:有私钥和公钥。 它们是一组,并且每组都是独一无二的。 没有第二组是完全相同的。
私钥可以随意给任何人,但公钥不能对外共享。
私钥和公钥都可以加密和解密。 加密的密钥必须使用同一组中的另一个密钥进行解密。 密钥的加密实际上是有规则的。
什么是私钥加密?###
假设有两个字母,一个是a,另一个是b。 我喜欢数字b,所以我会保留它并且不会告诉你(公钥)。 稍后我会告诉你,a是我的私钥。
我有一个文件,别人看不到php私钥,所以我用1加密。别人发现了这个文件,他不知道b是解密的公钥,所以他无法解密,只能我可以用它。
数字b是我的公钥php私钥,用于揭示秘密。 这样我就可以保护数据。
有人用我的私钥a加密了字符hello,加密后就变成了xxxxx,放到了网上。 其他人窃取了这个文件,他们无法解密它,因为他们不知道b是我的公钥。
只有我才能透露这个秘密。 揭秘后,我会打招呼。 这样,我们就可以传输加密数据。
公钥签名###
如果我用公钥加密一段数据(实际上只有我可以用公钥加密,因为只有我知道b是我的公钥),每个人都会看到我的内容,因为他们都知道我的私钥是a ,这些加密有什么好处?
有人说有人冒充我给他寄了一封信。 该怎么办? 我使用我的公钥 b 对内容为 c 的我要发送的信件进行加密。 加密后的内容是d,发给某人,然后告诉他泄露秘密,看看是不是c。 他用我的私钥a泄露了秘密,发现确实是c。 这时候他就会认为能用我的私钥解密的数据一定是用我的公钥加密的。 只有我知道我的私钥,所以他可以确认这确实是我发送的。 这样我们就可以确认发件人的身份。 这个过程称为数字签名。 其实具体过程稍微复杂一些。 使用公钥加密数据用于数字签名。
私钥和公钥是成对的,它们会互相暴露。
私钥被加密,公钥被公开。
公钥数字签名,私钥验证。
在这里写下图片描述
下面贴出PHP中使用私钥和公钥加密的代码以及需要注意的地方:
首先,私钥和公钥可以存储在文件和字符串中。 不过,作为新手,要注意的是,无论私钥还是公钥是放在文件中还是字符串上,都必须记住分支。 我刚开始从来没有分支,然后我总是犯错误,后来我知道我需要一个分支。 并且不要忘记前后的注释行。-----BEGINPUBLICKEY-----
下面这段话是错误的
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADxdfxfgcghCBiQKBgQCIgm80UzfD9lQ/tnASRCapNNaoTcodUfDzNYLWAxEMp8EtWkD4eZmWbMdaWKyShIOGS48NKdVGsAB+F4usW1VFtrbqOfKgBUxMJKz1YcciBiV3kvhHZI4/jq94E0qy1jxTNdralRhe+0/JklopEM9QWZScpBT4IXBfbMJ3JD5doQIDAQAB
-----END PUBLIC KEY-----
这段代码方法是正确的
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIgm80UzfD9lQ/tnASRCapNNao
TcodUfDzNYLWAxEMp8EtWkD4eZmWbMdaWKyShIOGS48NKdVGsAB+F4usW1VFtrbq
OfKgBUxMJKz1YcciBiV3kvhHZI4/jq94E0qy1jxTNdralRhe+0/JklopEM9QWZSc
pBT4IXBfbMJ3JD5doQIDAQAB
-----END PUBLIC KEY-----
存储处理后的私钥和公钥后,代码中需要使用的加密和解密就被揭示出来了。 使用的函数可以直接在PHP加密指南中查看。
首先是私钥加密:这里使用的函数是openssl_public_encrypt()
public function encrypt($data,$key_path){
$key = file_get_contents($key_path);
$encryptedList = array();
$step = 117;
$encryptedData = '';
$len = strlen($data);
for ($i = 0; $i < $len; $i += $step) {
$tmpData = substr($data, $i, $step);
$encrypted = '';
openssl_public_encrypt($tmpData, $encrypted, $key,OPENSSL_PKCS1_PADDING);
$encryptedList[] = ($encrypted);
}
$encryptedData = base64_encode(join('', $encryptedList));
return $encryptedData;
}
使用公钥解密(使用函数 openssl_private_decrypt)
private function decrypt($encryptedData){
if (empty($encryptedData)) {
return '';
}
$encryptedData = base64_decode($encryptedData);
$decryptedList = array();
$step = 128;
$len = strlen($encryptedData);
for ($i = 0; $i _key_pri), OPENSSL_PKCS1_PADDING);
$decryptedList[] = $decrypted;
}
return join('', $decryptedList);
使用公钥签名,使用的函数(openssl_get_privatekey)
private function rsa_sign($data){
//私钥加签
$res = openssl_get_privatekey(file_get_contents($this->_key_priva_mime));
openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA1);
openssl_free_key($res);
$sign = base64_encode($sign);
return $sign;
私钥签名验证(openssl_get_publickey)
private function _rsaCheckSign($data, $sign){
$pubKey = file_get_contents($this->_key_pub_mime);
$res = openssl_get_publickey($pubKey);
$result = (bool)openssl_verify($data, base64_decode($sign), $res);
openssl_free_key($res);
return $result;
}
ps:如果是文件格式的公钥,则需要使用file_get_contents,地址可以在括号内。