• 喜欢前端以及PHP的朋友们可以加PHP同好会QQ群 点击加入qq群
  • 最近在写一个项目---"小A微信托管平台",大家可以去帮忙测试一下!功能在不断完善中,敬请关注!点击进入
  • 本站使用了PHP8.1与HTTP2.0协议,速度简直超级快有木有?

Python,PHP Rsa 公钥加密私钥解密

后端 Mr.Adam 5年前 (2020-12-25) 1872次浏览 已收录 0个评论

Python,PHP Rsa 公钥加密私钥解密

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;
}

小 A 空间 , 版权所有丨如未注明转载 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Python,PHP Rsa 公钥加密私钥解密
喜欢 (2)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址