zoukankan      html  css  js  c++  java
  • Python使用rsa模块实现非对称加密与解密

    Python使用rsa模块实现非对称加密与解密

    1、简单介绍:

    RSA加密算法是一种非对称加密算法 是由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。
    RSA密钥至少为500位长,一般推荐使用1024位。RSA密钥长度随着保密级别提高,增加很快。
    由于RSA的特性,一个1024位的密钥只能加密117位字节数据,当数据量超过117位字节的时候,程序就会抛出异常。 ——来自大佬

    2、代码实现:

    来一段大佬的代码

    import rsa
    
    
    # 一、生成公钥及私钥, 并保存
    public_key, private_key = rsa.newkeys(1024)  # 生成公钥和私钥
    # 将生成的公钥和私钥进行转换,以便存储
    pub = public_key.save_pkcs1()
    pri = private_key.save_pkcs1('PEM')  # save_pkcsl()是内置方法,其默认参数是‘PEM’
    with open('pubkey.pem', mode='wb') as f, open('privkey.pem', mode='wb') as f1:
    	f.write(pub)  # 打开两个文件,分别存储公钥及私钥
    	f1.write(pri)
    
    
    # 二. 使用公钥加密, 私钥解密
    def func():
    	with open('pubkey.pem', mode='rb') as f, open('privkey.pem', 'rb') as f1:
    		pub = f.read()  # 从文件中再读出公钥和私钥
    		pri = f1.read()
    		public_key = rsa.PublicKey.load_pkcs1(pub)  # 转换为原始状态
    		private_key = rsa.PrivateKey.load_pkcs1(pri)
    	message = "rsa加密测试"
    	info = rsa.encrypt(message.encode('utf-8'), public_key)  # 使用公钥加密内容,内容必须是二进制
    	msg = rsa.decrypt(info, private_key)  # 使用私钥解密,获得解密后的内容
    	print(msg.decode('utf-8'))  # 使用之前记得先解码
    

    3、代码升级:

    现在我将上述的代码段封装成一个Rsa class(包含的方法有:__init__——初始化方法,key_transform_store——存储公钥与私钥的方法、encry——加密方法、decry——解密方法),使用的时候,直接将下面的代码段拎到我们需要的地方去引用:先创建一Rsa对象,然后调用里面的方法即可:

    import rsa
    
    
    class Rsa(object):
    	"""RSA加密、解密"""
    
    	def __init__(self, number, pub_path='public_key.pem', priv_path='private_key.pem'):
    		"""
    
    		:param pub_path: the path to public key, default its path is public_key.pem
    		:param priv_path: the path to private key, default its path is private_key.pem
    		"""
    		# Generate the public and private keys, and returns them
    		self.public_key, self.private_key = rsa.newkeys(number)
    
    		self.public_key_path = pub_path
    		self.private_key_path = priv_path
    
    	def key_transform_store(self):
    		"""
    		convert and save the generated public and private keys to a file
    		:return: None
    		"""
    		# convert the generated public and private keys for storage
    		pub = self.public_key.save_pkcs1()
    		pri = self.private_key.save_pkcs1('PEM')
    
    		# open two files to store the public key and private key respectively
    		
    		with open(self.public_key_path, mode='wb') as f:
    			f.write(pub)
    
    		with open(self.private_key_path, mode='wb') as f1:
    			f1.write(pri)
    
    	def encry(self, info):
    		"""
    		encrypt information
    		:param info: the original string information to be encrypted
    		:return:info_encrypted
    		"""
    		# read the public key from the file
    		with open(self.public_key_path, mode='rb') as f:
    			pub = f.read()
    			# convert pub to original state
    			public_key = rsa.PublicKey.load_pkcs1(pub)
    
    		# use the public key to encrypt the content, which must be binary
    		info_encrypted = rsa.encrypt(info.encode('utf-8'), public_key)
    		return info_encrypted
    
    	def decry(self, info_encrypted):
    		"""
    		decrypt information
    		:param info_encrypted: encrypted information
    		:return: info
    		"""
    		# read the private key from the file
    		with open(self.private_key_path, 'rb') as f:
    			pri = f.read()
    			# convert pri to original state
    			private_key = rsa.PrivateKey.load_pkcs1(pri)
    
    		# decrypt with private key to obtain the decrypted content
    		msg = rsa.decrypt(info_encrypted, private_key)
    		info = msg.decode('utf-8')  # decode
    		return info
    
    
    rsa_obj = Rsa(1024)  # 实例化
    rsa_obj.key_transform_store()  # 
    info_encrypted = rsa_obj.encry('我是真心喜欢你的。')  # 加密
    print(info_encrypted)
    info = rsa_obj.decry(info_encrypted)  # 解密
    print(info)  # 我是真心喜欢你的。
    

    这里会出现一个问题:由于RSA的特性,一个1024位的密钥只能加密117位字节数据,当数据量超过117位字节的时候,程序就会抛出异常。如下测试会抛出:OverflowError: 189 bytes needed for message, but there is only space for 117

    rsa_obj = Rsa(1024)  # 实例化
    rsa_obj.key_transform_store()  # 
    info_encrypted = rsa_obj.encry('我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。')  # 加密
    print(info_encrypted)
    info = rsa_obj.decry(info_encrypted)  # 解密
    print(info)
    

    。。。。。。

    后记: 通常使用中, 会先对数据进行bas64加密, 再对加密后的内容使用rsa加密, 最后对rsa解密后的内容进行bas64解密。

    以上。

  • 相关阅读:
    OSX安装nginx和rtmp模块(rtmp直播服务器搭建)
    用runtime来重写Coder和deCode方法 归档解档的时候使用
    Homebrew安装卸载
    Cannot create a new pixel buffer adaptor with an asset writer input that has already started writing'
    OSX下面用ffmpeg抓取桌面以及摄像头推流进行直播
    让nginx支持HLS
    iOS 字典转json字符串
    iOS 七牛多张图片上传
    iOS9UICollectionView自定义布局modifying attributes returned by UICollectionViewFlowLayout without copying them
    Xcode6 iOS7模拟器和Xcode7 iOS8模拟器离线下载
  • 原文地址:https://www.cnblogs.com/sirxy/p/12141633.html
Copyright © 2011-2022 走看看