Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >python使用RSA加密算法

python使用RSA加密算法

作者头像
全栈程序员站长
发布于 2022-08-20 02:14:15
发布于 2022-08-20 02:14:15
2.7K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

上一篇文章介绍了RSA加密原理以及自己的一些理解,现在我们就来实际操作一下,使用python语言如何来实现RSA的加密—解密—签名—验签这一系列过程。

##一、生成公钥、私钥对 使用openssl工具生成RSA公钥、私钥对。

1.下载openssl工具。点我下载一点我下载二 2.打开 openssl 文件夹下的 bin 文件夹,执行 openssl.exe 文件; 3.生成RSA私钥命令:

这里生成的密钥文件是2048比特。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
genrsa -out rsa_private_key.pem 2048

4.生成RSA公钥命令: 注意,公钥和私钥是成对的,所以你在生成一个后,另一个的生成是基于前一个的文件名,否则生成的不是一对哦!!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

生成后的文件应该在你的用户目录下,或者在openssl的bin文件夹下(有时候在有时又不在,真是搞不懂,反正你就在这两个地方都找一下,肯定在的)。

**5.这里介绍一下RSA密钥文件的规律,**文件名都是以.pem为后缀,生成的RSA密钥,可以看到都是 以-----BEGIN RSA PRIVATE KEY-----开头,-----END RSA PRIVATE KEY-----结尾的没有换行的字符串,这个就是原始的 RSA 私钥。

##二、安装python支持的加密库—pycryptodome

我用的python3.6版本,网上搜了一下,在python3.6之前的版本大部分是用pycrypto来进行加密的,而在python3.6之后,因无人维护pycrypto,所以改名为pycryptodome,这个库的强大之处在于,他是pycrypto库的扩展,用起来更加方便,更灵活啊~~功能杠杠滴

###1.安装pycryptodome 如果你安装了pip,那么就很简单了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip3 install pycryptodome  

###2.将密钥文件导入到程序中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from Crypto.PublicKey import RSA

# 读取标准的rsa公私钥pem文件
def load_rsa_file(fn):
    key = None
    try:
        key = RSA.importKey(open(fn).read())
    except Exception as err:
        print('导入rsa的KEY文件出错', fn, err)
    return key


# 标准字符串密钥转rsa格式密钥
def rsa_key_str2std(skey):
    ret = None
    try:
        ret = RSA.importKey(skey)
    except Exception as err:
        print('字符串密钥转rsa格式密钥错误', skey, err)
    return ret

###3.RSA加密

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from Crypto.Cipher import PKCS1_OAEP

# RSA_加密
def rsa_enc(data, rsa_key):
    ciphertext = b''
    try:
        cipher = PKCS1_OAEP.new(rsa_key)
        ciphertext = cipher.encrypt(data)
    except Exception as err:
        print('RSA加密失败', '', err)
    return ciphertext

由于RSA在加密过程中,每次加密只能加密最大长度的字符串,如果你的加密数据超长,在加密过程中需要分段加密,同理,解密也是分段解密的。

1024位的证书,加密时最大支持117个字节,解密时为128; 2048位的证书,加密时最大支持245个字节,解密时为256。

加密时支持的最大字节数:证书位数/8 -11(比如:2048位的证书,支持的最大加密字节数:2048/8 – 11 = 245) 其中,11位字节为保留字节。 上面我的密钥文件是2048比特,所以加密分块长度为245字节。

###4.加密分块

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 根据key长度计算分块大小
def get_block_size(rsa_key):
	try:
		# RSA仅支持限定长度内的数据的加解密,需要分块
		# 分块大小block_reversed_size=11
		reserve_size = block_reversed_size
		key_size = rsa_key.size_in_bits()
		if (key_size % 8) != 0:
			raise RuntimeError('RSA 密钥长度非法')

		# 密钥用来解密,解密不需要预留长度
		if rsa_key.has_private():
			reserve_size = 0

		bs = int(key_size / 8) - reserve_size
	except Exception as err:
		print('计算加解密数据块大小出错', rsa_key, err)
	return bs

# 返回块数据
def block_data(data, rsa_key):
	bs = get_block_size(rsa_key)
	for i in range(0, len(data), bs):
		yield data[i:i + bs]

RSA在解密分段时与加密时用的分段大小无关,都是按照密钥长度/8来分段解密的。

###5.RSA解密

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from Crypto.Cipher import PKCS1_OAEP

# RSA解密
def rsa_dec(data, rsa_key):
    ret_data = b''
    try:
        cipher = PKCS1_OAEP.new(rsa_key)
        ret_data = cipher.decrypt(data)
    except Exception as err:
        print('RSA解密失败', '', err)
    return ret_data

###6.RSA签名

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256

# RSA签名
def rsa_sign(data, rsa_key):
    signature = ''
    try:
        h = SHA256.new(data)
        signature = pkcs1_15.new(rsa_key).sign(h)
    except Exception as err:
        print('RSA签名失败', '', err)
    return signature

###7.RSA验签名

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# RSA签名验证
def rsa_sign_verify(data, sig, rsa_key):
    try:
        h = SHA256.new(data)
        pkcs1_15.new(rsa_key).verify(h, sig)
        ret = True
    except (ValueError, TypeError):
        ret = False
    return ret

###8.RSA加解密类(我将RSA加解密封装成一个类,方便后续直接调用),完整代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding: utf-8 -*-
import Crypto.Cipher as Cipher
import Crypto.Signature as Sign
import Crypto.Hash as Hash
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_v1_5_cipper
from Crypto.Signature import PKCS1_v1_5 as PKCS1_v1_5_sign
from Crypto.Hash import SHA1


class Rsa:
    """RSA加解密签名类
    """

    def __int__(self, ciper_lib=PKCS1_v1_5_cipper, sign_lib=PKCS1_v1_5_sign, hash_lib=SHA1,
                pub_file=None, pri_file=None, pub_skey=None, pri_skey=None, pub_key=None, pri_key=None,
                reversed_size=11):

        # 加解密库
        self.ciper_lib = ciper_lib
        self.sign_lib = sign_lib
        self.hash_lib = hash_lib

        # 公钥密钥
        if pub_key:
            self.pub_key = pub_key
        elif pub_skey:
            self.pub_key = RSA.importKey(pub_skey)
        elif pub_file:
            self.pub_key = RSA.importKey(open(pub_file).read())

        if pri_key:
            self.pri_key = pri_key
        elif pri_skey:
            self.pri_key = RSA.importKey(pri_skey)
        elif pri_file:
            self.pri_key = RSA.importKey(open(pri_file).read())

        # 分块保留长度
        self.block_reversed_size = reversed_size

    # 根据key长度计算分块大小
    def get_block_size(self, rsa_key):
        try:
            # RSA仅支持限定长度内的数据的加解密,需要分块
            # 分块大小
            reserve_size = self.block_reversed_size
            key_size = rsa_key.size_in_bits()
            if (key_size % 8) != 0:
                raise RuntimeError('RSA 密钥长度非法')

            # 密钥用来解密,解密不需要预留长度
            if rsa_key.has_private():
                reserve_size = 0

            bs = int(key_size / 8) - reserve_size
        except Exception as err:
            print('计算加解密数据块大小出错', rsa_key, err)
        return bs

    # 返回块数据
    def block_data(self, data, rsa_key):
        bs = self.get_block_size(rsa_key)
        for i in range(0, len(data), bs):
            yield data[i:i + bs]

    # 加密
    def enc_bytes(self, data, key=None):
        text = b''
        try:
            rsa_key = self.pub_key
            if key:
                rsa_key = key

            cipher = self.ciper_lib.new(rsa_key)
            for dat in self.block_data(data, rsa_key):
                cur_text = cipher.encrypt(dat)
                text += cur_text
        except Exception as err:
            print('RSA加密失败', data, err)
        return text

    # 解密
    def dec_bytes(self, data, key=None):
        text = b''
        try:
            rsa_key = self.pri_key
            if key:
                rsa_key = key

            cipher = self.ciper_lib.new(rsa_key)
            for dat in self.block_data(data, rsa_key):
                if type(self.ciper_lib) == Cipher.PKCS1_OAEP:
                    cur_text = cipher.decrypt(dat)
                else:
                    cur_text = cipher.decrypt(dat, '解密异常')
                text += cur_text
        except Exception as err:
            print('RSA解密失败', data, err)
        return text

    # RSA签名
    def sign_bytes(self, data, key=None):
        signature = ''
        try:
            rsa_key = self.pri_key
            if key:
                rsa_key = key

            h = self.hash_lib.new(data)
            signature = self.sign_lib.new(rsa_key).sign(h)
        except Exception as err:
            print('RSA签名失败', '', err)
        return signature

    # RSA签名验证
    def sign_verify(self, data, sig, key=None):
        try:
            rsa_key = self.pub_key
            if key:
                rsa_key = key
            h = self.hash_lib.new(data)
            self.sign_lib.new(rsa_key).verify(h, sig)
            ret = True
        except (ValueError, TypeError):
            ret = False
        return ret


def main():
    pass


if __name__ == '__main__':
    main()

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/136542.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月4,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
python实现AES/DES/RSA/MD5/SM2/SM4/3DES加密算法模板汇总
都是作者累积的,且看其珍惜,大家可以尽量可以保存一下,如果转载请写好出处https://www.cnblogs.com/pythonywy
小小咸鱼YwY
2020/11/24
5K0
RSA加密解密(无数据大小限制,php、go、java互通实现)
RSA加解密中必须考虑到的密钥长度、明文长度和密文长度问题。明文长度需要小于密钥长度,而密文长度则等于密钥长度。因此当加密内容长度大于密钥长度时,有效的RSA加解密就需要对内容进行分段。
双鬼带单
2019/07/30
5.1K0
Crypto算法库详解
Crypto 算法库在 python 中最初叫 pycrypto,这个作者有点懒,好几年没有更新,后来就有大佬写了个替代库 pycryptodome。这个库目前只支持 python3,安装也很简单pip install pycryptodome就行了!详细的用法可以看看 官方文档
py3study
2020/01/02
4K0
[1249]python实现rsa非对称加密解密
这两种方法都可以实现RSA加密,第一种方法使用了Python的内置模块rsa,而第二种方法使用了第三方库cryptography。请注意,第二种方法需要先安装cryptography库。两种方法的核心思路是相同的,即生成密钥对、加密和解密过程,只是具体的实现细节有所不同。
周小董
2023/12/25
1.7K0
Python接口自动化之通过RSA加解密
Hi,大家好。在之前的文章:Python实现各种加密,接口加解密不再难,介绍了Base64、MD5、Sha1、Secret、RSA等几种加密方式,今天结合项目具体介绍RSA加密。
可可的测试小栈
2022/03/10
2.4K0
Python接口自动化之通过RSA加解密
利用Crypto++实现RSA加密算法
之前做一个项目用到crypto++加密库,可以从官网下载对应的源码,其中有一个test.c文件,详细的演示了各种加密算法的使用方法,因此,在其基础上,我将aes、rsa、MD5进行了简单的封装,以便于更好的使用 MyRSA.h头文件如下: /* * MyRSA.h * * Created on: 2013-3-7 * Author: wzb */ #ifndef MYRSA_H_ #define MYRSA_H_ #define CRYPTOPP_ENABLE_NAMESP
一灰灰blog
2018/02/06
2.6K0
如何使用RSA 对数据加解密和签名验签?一篇文章带你搞定
加密是指利用某个值(密钥)对明文的数据通过一定的算法变换加密(密文)数据的过程,它的逆向过程叫解密。
用户8949263
2022/04/08
5.9K0
如何使用RSA 对数据加解密和签名验签?一篇文章带你搞定
RSA 加密算法与 golang 代码实现
最近参与借贷业务的开发,接口传输过程中需要使用 RSA 加密算法对请求和返回进行加密,所以写了这篇博客。主要介绍 RSA 的基础知识和 golang 使用例子
_春华秋实
2023/11/27
5110
Python 实现RSA SHA-1签名
今天对接业务接口,传递的参数需要用RSA签名,三方只给了java的RSA签名Demo;但我们这边后端采用python开发,因此需要用Python来实现RSA签名。
py3study
2020/01/07
1.9K0
接口数据使用了 RSA 加密和签名?一篇文章带你搞定
接下来我们就来使用 python 来实现 RSA 加密与签名,使用的第三方库是 Crypto:
程序员白楠楠
2021/08/27
2.1K0
学一学RSA加密吧,下次对接的时候就不会被对方Diss了
RSA加密算法:是一种非对称加密算法,它需要两个密钥,一个是公开密钥,另一个是私有密钥;公钥用作加密,私钥则用作解密。只能用相对应的私钥才能解密并得到原本的明文,最初用来加密的公钥不能用作解密,加密和解密需要两个不同的密钥,因此被称为非对称加密,加密的双方在开发前根据明文的长度/数据加密等级需要协定好密钥的位数,目前可使用1024、2048、4096字节的密钥(key),安全性随字节长度升高而升高,性能随之而下降,时间复杂度为O(nlogn)。
关忆北.
2021/12/07
1.2K0
非对称密钥沉思系列(1):RSA专题之PKCSv1.5填充模式下的选择性密文攻击概述
本文主要梳理RSA 在PKCSv1.5 Padding模式下的 Oracle攻击。
密码学人CipherHUB
2022/12/05
5.7K12
非对称密钥沉思系列(1):RSA专题之PKCSv1.5填充模式下的选择性密文攻击概述
数据安全RSA算法,加密解密,签名验签流程详解
(1)、乙方生成一对密钥即公钥和私钥,私钥不公开,乙方自己持有,公钥为公开,甲方持有。
知了一笑
2019/10/23
2.2K0
数据安全RSA算法,加密解密,签名验签流程详解
Python的RSA加密和PBE加密
最近在写接口的时候,遇到了需要使用RSA加密和PBE加密的情况,对方公司提供的DEMO都是JAVA的,我需要用python来实现。 在网上搜了一下,python的RSA加密这块写的还是比较多的,但是PBE较少。所以我就讲讲我在RSA加密上面遇到的坑,大家权当一乐。PBE加密里面的盐、密钥。
py3study
2020/01/06
1.8K0
Web Crypto API简介
早年在web端做对称/非对称的加解密还是个很复杂的操作,由于没有js层面的基础库。很多基础设施只能从头开始。
王沛文
2018/07/31
6.4K0
python进行RSA加密
RSA加密是一种非对称加密算法。被公钥加密的数据只能用私钥解密,被私钥加密的数据只能被公钥解密。公钥和私钥只是对两种密钥的使用场景以及是否对外公开来区分的,本质上区别不大。
灯珑LoGin
2022/10/31
1.2K0
java与openssl的rsa算法互
说明    1.java生成的公私钥格式为 pkcs8, 而openssl默认生成的公私钥格式为 pkcs1,两者的密钥实际上是不能直接互用的     2.java采用的rsa默认补齐方式是pkcs1, 因此互用的时候需要将openssl中的补齐方式设置为RSA_PKCS1_PADDING     3.rsa加密中,加密数据长度有限制,不能超过密钥长度-11, 如密钥为1024位,则最长的加密数据位117字节; 加密后的密文长度总是为密钥的一半,即1024位的密文为512位 RSA加密常用的填充方式有下
一灰灰blog
2018/02/06
4.2K0
python3中Crypto的AES和RSA
RSA加密一般使用RSA/ECB/PKCS1Padding(算法/工作模式/填充方式),AES加密一般使用AES/ECB/PKCS5Padding。但python中的补码需要自己进行填充。
静默加载
2020/05/29
1.6K0
Python crypto模块实现RSA和AES加密解密
RSA加密算法是一种非对称加密算法。RSA 是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的。
Python碎片公众号
2021/02/26
10.6K0
Python crypto模块实现RSA和AES加密解密
【深度知识】RSA加密、解密、签名、验签的原理及方法
RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。者能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称之为公钥和私钥。如果用公钥进行加密,则只能通过对应的私钥去解密,如果用私钥进行加密,则只能通过对应的公钥去解密。两者之间有数字相关,该加密发酸的原理就是对一极大整数做因数分解的困难行来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)
辉哥
2021/03/02
7.1K0
【深度知识】RSA加密、解密、签名、验签的原理及方法
相关推荐
python实现AES/DES/RSA/MD5/SM2/SM4/3DES加密算法模板汇总
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验