Python,PHP Rsa 公钥加密私钥解密
Rsa 是一种非对称加密算法,非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
在这里分享之前使用到的 python 和 php 进行点对点(socket)通信中使用的 rsa 加密方式(公钥加密,私钥解密).
生成 rsa 公钥和私钥
在这里使用 linux 下的 openssl
#首先进入 openssl openssl #生成 1024 长度的私钥 genrsa -out {私钥文件名称}.pem 1024 #根据私钥文件生成一个公钥 rsa -in {私钥文件名称}.pem -pubout -out {公钥文件名称}.pem #退出 openssl exit
这样就得到一对 Rsa 公钥和私钥
PHP 使用 RSA 公钥加密字符串
php 使用openssl_public_encrypt
函数来加密公钥
/* openssl_public_encrypt 函数如下 */ function openssl_public_encrypt($data, &$crypted, $key, $padding = OPENSSL_PKCS1_PADDING) { } /* 值得注意的是,如果选择密钥是 1024bit 长的,那么支持加密的明文长度字节最多只能是 1024/8=128 字节; 如果加密的 padding 填充方式选择的是 OPENSSL_PKCS1_PADDING(这个要占用 11 个字节),那么明文长度最多只能就是 128-11=117 字节; 所以使用 rsa 加密的时候需要判断字符串字节是否大于 117,对字节数大于 117 的字符串需要分片加密再拼接起来. 以下是使用 PHP 进行 RSA 加密的函数. */ function rsa_encrypt($data,$public_key){ $mask = "&&"; $len = strlen($data); $min = 117; if($len <= $min){ openssl_public_encrypt($data, $encrypted, $public_key); $encrypted = base64_encode($encrypted); return $encrypted; }else{ $new_str = ""; foreach(str_split($data,$min) as $chunk){ openssl_public_encrypt($chunk, $encrypted, $public_key); $encrypted = base64_encode($encrypted); $new_str .= $encrypted.$mask; } $new_str = substr($new_str,0,-2); return $new_str; } }
使用 Python RSA 私钥解密
首先使用pip
安装 RSA 软件包
pip install pyCrypto rsa
#!/usr/bin/python # -*- coding: utf-8 -*- import io import base64 from Crypto import Random from Crypto.Hash import SHA from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5 from Crypto.PublicKey import RSA import sys reload(sys) sys.setdefaultencoding('utf-8') def rsa_decrypt(sign_str,privte_pem_path,mask): with open(privte_pem_path) as f: key = f.read() rsakey = RSA.importKey(key) cipher = Cipher_pkcs1_v1_5.new(rsakey) r_str = "" crypt_arr = sign_str.split(mask) for crypt_str in crypt_arr: r_str += cipher.decrypt(base64.b64decode(crypt_str),"error") return r_str
RSA 私钥签名公钥验签
RSA 也可以使用私钥对数据加密,另一边使用公钥验签,这样就可以保证数据不会被中途篡改
Python RSA 私钥签名
#!/usr/bin/python # -*- coding: utf-8 -*- import io import base64 from Crypto import Random from Crypto.Hash import SHA from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5 from Crypto.PublicKey import RSA import sys reload(sys) sys.setdefaultencoding('utf-8') def rsa_encrypt(sign_str,privte_pem_path): with open(privte_pem_path) as f: key = f.read() rsakey = RSA.importKey(key) verifier = Signature_pkcs1_v1_5.new(rsakey) rand_hash = SHA.new() rand_hash.update(sign_str.encode()) s = rand_hash.hexdigest() sign_str = verifier.sign(s) sign_str = base64.b64encode(sign_str) return sign_str
PHP RSA 公钥验签
function rsa_verify($sign,$str,$public_key){ $data = base64decode($sign); $publicKeyId = openssl_pkey_get_public($public_key); $result = openssl_verify($str, $data, $publicKeyId,OPENSSL_ALGO_SHA1); openssl_free_key($publicKeyId); return $result === 1 ? true : false; }