一、使用php生成RSA公钥私钥及进行加密解密示例
搜了搜百度,很少有真正关于使用php生成RSA公钥私钥的文章,大多都是拿一个现成的公钥私钥字符串或文件在那里试验 (publish:October 18, 2016 -Tuesday),多搜索了一些发现有调用RSA.php类的,而这些方法里还需要调用MATH类和BCMATCH之类的,反正我也没有试验成功。最后在PHP手册上找到了一个函数:openssl_pkey_export 进而发现了PHP生成公钥私钥的方法。PHP的手册里也有一些示例。
使用php生成公钥私钥的核心方法:openssl_pkey_new,用PHP试验了一下。
1. 使用php生成公钥私钥代码如下:
<?php
#author:kermit
#data:2016-10-18
#note:php rsa secret
//创建公钥和私钥
$res=openssl_pkey_new(array('private_key_bits' => 512)); #此处512必须不能包含引号。
//提取私钥
openssl_pkey_export($res, $private_key);
//生成公钥
$public_key=openssl_pkey_get_details($res);
/*Array
(
[bits] => 512
[key] =>
[rsa] =>
[type] => 0
)*/
$public_key=$public_key["key"];
//显示数据
var_dump($private_key);
var_dump($public_key);
//要加密的数据
$data = "Web site:http://47.93.183.36";
echo '加密的数据:'.$data."\n";
//私钥加密后的数据
openssl_private_encrypt($data,$encrypted,$private_key);
//加密后的内容通常含有特殊字符,需要base64编码转换下
$encrypted = base64_encode($encrypted);
echo "私钥加密后的数据:".$encrypted."\n";
//公钥解密
openssl_public_decrypt(base64_decode($encrypted), $decrypted, $public_key);
echo "公钥解密后的数据:".$decrypted,"\n-------------------------------\n";
//----相反操作。公钥加密
openssl_public_encrypt($data, $encrypted, $public_key);
$encrypted = base64_encode($encrypted);
echo "公钥加密后的数据:".$encrypted."\n";
openssl_private_decrypt(base64_decode($encrypted), $decrypted, $private_key);//私钥解密
echo "私钥解密后的数据:".$decrypted."\n";
2. 在服务器上使用php运行结果如下:
[root@kermit ~]# php -f makersa.php
string(522) "-----BEGIN PRIVATE KEY-----
MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA2tIoxjY4S02v7HVn
g9b20Q8Cjbq6dnAAbC1naNwGZzEEqmR4GKNvTFEdp+O8e945lKa79goCYjdVoyxL
S3SKjQIDAQABAkEAhpxaMPUR1GFKI/BlaZlH5HuTWpTQOCPWXrXfs4YG+lrtwd8P
vEKSJeRNCWWpY0zwOoDQQBB9JBO6wlnsI1JcAQIhAPeDqBlLX1Q2F//h1OdPYUIR
1r0VbqiAOMTmCzmzSRTBAiEA4lKr5r5RC0+VraZxq1W/UBuBuQYKcLAUQ4l2a40N
7M0CIC56389YMx+qRNl9fDCv3HC+zteVNcGYypBXLtZ4D4pBAiAUa3MZEYjMZXTS
wxa0Z7soJiMxJ2tfuXNKmKd3krVz7QIgDWHPu3yTDhYbK2nV41iDuJ/oSZnZb7S8
9uGYFrj+ZyE=
-----END PRIVATE KEY-----
"
string(182) "-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANrSKMY2OEtNr+x1Z4PW9tEPAo26unZw
AGwtZ2jcBmcxBKpkeBijb0xRHafjvHveOZSmu/YKAmI3VaMsS0t0io0CAwEAAQ==
-----END PUBLIC KEY-----
"
加密的数据:Web site:http://47.93.183.36
私钥加密后的数据:PKbSJnCiWqNB58fXG9aBXyDTudd/GnEYQtG7mK80/+Z3IaGu5wORL5Cwq7l9b00Xtao6w2tnboEz+D+O/c4m+w==
公钥解密后的数据:Web site:http://47.93.183.36
-------------------------------
公钥加密后的数据:Pq0Sm4pWSrF7wtckqbdjAaU7H002zdfw5ZmL4wMyTdzqxwS9bNyw5k4DFnZZKCKN26gu3bhikd5G7zXl22y1rQ==
私钥解密后的数据:Web site:http://47.93.183.36
[root@kermit ~]#
3. 本文发布后的用户评论内容转载如下:
Level : 1. User:us20180209154626-510 Time:2018-02-09 15:50:34
找了这么久终于找到好的文章了,谢谢了。
Level : 2. User:us20180209154626-510 Time:2018-02-09 15:51:42
我q481719882希望能一起探讨一下
Level : 3. User:us20180627154859-487 Time:2018-06-27 15:53:36
私钥不能用啊,哥
Level : 4. User:us20181009174904-135 Time:2018-10-09 17:50:25
人家这私钥是演示的,主要说的是怎么用PHP来生成公钥和私钥,你直接拿来用了人才
4. 其它备注
上述PHP生成RSA的程序大约是2016、2017接触使用的,下述的python版本大约是2022年因为业务需要而使用的。
二、Python使用RSA实现非对称加解密
Python使用RSA非对称加解密需要依赖Crypto库。不然会报No module named 'Crypto'的错误。Crypto库是一个用c++编写的密码类库。Crypto算法库在python中最初叫pycrypto,之后没有再更新过,后来有人在此基础上写了个替代库pycryptodome。这个库目前只支持python3,因此要使用Crypto(Python3.*),直接安装pip install pycryptodome。Crypto库中的功能分类如下:
- 常见对称密码在 Crypto.Cipher 库下,主要有:DES 3DES AES RC4 Salsa20
- 非对称密码在 Crypto.PublicKey 库下,主要有:RSA ECC DSA
- 哈希密码在 Crypto.Hash 库下,常用的有:MD5 SHA-1 SHA-128 SHA-256
- 随机数在 Crypto.Random 库下
- 实用小工具在 Crypto.Util 库下
- 数字签名在 Crypto.Signature 库下
第一步:#安装Crypto库
pip install pycryptodome -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
第二步:python使用RSA实现非对称加解密程序实例如下:
import base64
from Crypto import Random
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.PublicKey import RSA
# 伪随机数,创建rsa算法实例
random_generator = Random.new().read
rsa = RSA.generate(1024, random_generator)
# 生成秘钥对的
private_pem = rsa.exportKey()
print("private_key:", private_pem)
public_pem = rsa.publickey().exportKey()
print("public_key:", public_pem)
# 用公钥加密,被加密的数据后面.encode("utf8")不能省略
msg = 'test'
message = msg.encode("utf8")
# 导入公钥加密并对数据加密(后使用)
rsakey = RSA.importKey(public_pem)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
cipher_text = base64.b64encode(cipher.encrypt(message))
# 可以不使用base64编码
#cipher_text = cipher.encrypt(message)
print("加密后:", cipher_text)
# 用私钥解密
rsakey = RSA.importKey(private_pem)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
# 使用base64解密,(在前端js加密时自动是base64加密)
text = cipher.decrypt(base64.b64decode(cipher_text), random_generator)
# text = cipher.decrypt(cipher_text, random_generator)
print("加密前:", text)
第三步:最终输出结果示例:
private_key: b'-----BEGIN RSA PRIVATE KEY-----\nMIICXAIB..
public_key: b'-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSI
加密后: b'CpXsS9Veqs+Kk+4PaXTaYbizUAlJer
加密前: b'test'