Python工具箱系列(十八)

非对称加解密应用广泛,它的存在是致力于解决密钥通过公共信道传输这一经典难题。对称加密有一个天然的缺点,就是加密方和解密方都要持有同样的密钥,而这个密钥在传递过程中有可能会被截获,从而使加解密失效。难不成还要为密钥的传输再做一次加密?这样不就陷入了死循环?或许有人在想,密钥即使被盗取,不还有加密算法保证信息安全吗?但任何算法最终都会被破译,所以不能依赖算法的复杂度来保证安全。

可能的解决方案如下:

  • 事先共享密
  • 钥密钥分配中心
  • Diffie-Hellman密钥交换
  • 非对称加密

非对称加密就是一种广泛应用的加解密技术。非对称加密需要4个密钥。通信双方各自准备一对公钥和私钥。其中公钥是公开的,由信息接受方提供给信息发送方。公钥用来对信息加密。私钥由信息接受方保留,用来解密。既然公钥是公开的,就不存在保密问题。也就是说非对称加密完全不存在密钥配送问题。

下面是一个简单的场景:

  • 小明确定了自己的私钥mPrivateKey,公钥 mPublicKey。自己保留私钥,将公钥mPublicKey发给了小红。
  • 小红确定了自己的私钥hPrivateKey,公钥 hPublicKey。自己保留私钥,将公钥hPublicKey发给了小明。
  • 小明发送信息“周六早10点智慧谷见”,并且用小红的公钥hPublicKey进行加密。
  • 小红收到信息后用自己的私钥hPrivateKey进行解密。然后回复 “收到,不要迟到” 并用小明的公钥mPublicKey加密。
  • 小明收到信息后用自己的私钥mPrivateKey进行解密。

由于非对称密钥的特点,没有私钥就无法解密配对的公钥加密的信息,所以小明不担心自己公钥的任意发布、复制。同一公钥无法对此公钥加密的信息解密。所以,问题就变成了,只要保存好私钥就可以保证数据传输的安全,而私钥不需要在公共信息网络上传递,安全性是有基本保障的。

RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的。RSA是现在使用最为广泛的非对称加密算法。其原理本文不再赘述,毕竟本系列的文章重在实用。而一旦某一天发现了快速做质因数分解的算法,那么RSA就不再安全。

需要注意的是:

  • 非对称加密的处理速度只有对称加密的几百分之一。不适合对很长的消息做加密。
  • 1024bit的RSA不应该再被新的应用使用。至少要2048bit的RSA。
  • RSA解决了密码配送问题,但是效率更低。所以有些时候,根据需求可能会配合使用对称和非对称加密,形成混合密码系统,各取所长。

下面使用RSA进行数据加解密,先安装必要的模块:

 

pip install pycryptodome

生成密钥对的代码如下:

from Crypto import Random
from Crypto.PublicKey import RSA
 
 
random_generator = Random.new().read
rsa = RSA.generate(2048, random_generator)
# 生成私钥
private_key = rsa.exportKey()
print(private_key.decode('utf-8'))
# 生成公钥
public_key = rsa.publickey().exportKey()
print(public_key.decode('utf-8'))

with open('demo_private_key.pem', 'wb')as f:
    f.write(private_key)
    
with open('demo_public_key.pem', 'wb')as f:
    f.write(public_key)

也可以直接使用命令生成密钥对:

openssl genrsa -out rsa_private_key.pem 1024
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

将公钥文件通过电邮、QQ、微信等各种通信方式发送给对方。此时就具备了相互加密通信的可能性。

以下代码演示了发送的过程:

 

import base64
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher

def get_key(key_file):
    with open(key_file) as f:
        data = f.read()
        key = RSA.importKey(data)

    return key

def encrypt_data(msg,key):
    cipher = PKCS1_cipher.new(key)
    encrypt_text = base64.b64encode(cipher.encrypt(bytes(msg.encode("utf8"))))
    return encrypt_text.decode('utf-8')

public_key = get_key('demo_public_key.pem')
encryptedmsg = encrypt_data("hello,tiangong",public_key)
print(encryptedmsg)
with open("encryptmsg.txt", "w", encoding='utf-8') as output_file:
    output_file.write(encryptedmsg)

以上代码将明文“hello,tiangong”通过公钥变换成为密文,并且保存在文件encryptmsg.txt。

内容如下所示:

 

jFabADeOZOx44R73gUvD9KwKy7nmhzf4fMeP2YBo0ff2DCv/B/2jYD2s6n0p8El2Nt/bnLdGAPKhC/HCv6AzNDG2bjSDLjn9Uy+aWe5h568Z4cPzzmlkIDbOwjCv1VMXaonV28vLW1mznbVLDSOT0Qd13D3KcaoZLRZRzvhyUAe52Yuizi3wfrhBrnfEXdtZzIA5FSRauxT77l/d81RmMbbQk+uN+E8aC3XwJOHfEGhvimU9gcv2NVyh4AI1Gqjfq61KbS/I4Iwo2knHnHHssGLeO6jxk/5JkNw7I8PO+qc27KdF3Ye4uQ+Woy0RoJ6LyFi41wJjs9mk8YJu9DHevg==

我们假设发送方通过各种方式(socket、电邮、微信等)将密文内容发送给了接收者,接收者使用自己的私钥进行解密。

其代码如下:

 

import base64
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher

def get_key(key_file):
    with open(key_file) as f:
        data = f.read()
        key = RSA.importKey(data)

    return key

def decrypt_data(encrypt_msg,key):
    cipher = PKCS1_cipher.new(key)
    back_text = cipher.decrypt(base64.b64decode(encrypt_msg), 0)
    return back_text.decode('utf-8')

with open("encryptmsg.txt", "r", encoding='utf-8') as output_file:
    encryptedmsg = output_file.read()
    
private_key = get_key('demo_private_key.pem')
plainmsg = decrypt_data(encryptedmsg,private_key)
print(plainmsg)

运行后即可解出密文。以上就是一个单向加解密的完整过程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python工具箱系列(十八) - Python技术站

(0)
上一篇 2023年4月2日 下午4:20
下一篇 2023年4月2日 下午4:20

相关文章

  • Python工具箱系列(六)

    相比较于windows下安装python,在Linux下安装python实际上是一个非常困难的选择。首先要解决的就是选择哪个发行版本的问题。Linux的内核掌握在技术团队中,但是Linux发行版本则掌握在不同的公司手中。不同的公司出于不同的考虑,在Linux内核的基础上,打包了不同的应用程序,安装了不同的包管理器,实现了不同的发布策略,这就导致了数以百计的发…

    Python开发 2023年4月2日
    00
  • Python工具箱系列(九)

    在计算机世界里,信息安全始终占据着重要的地位,我们随处就可以看到信息安全的应用: ◆ 访问网站时,使用https而不是http会使访问者的安全性大大提升 ◆ 下载文件时,正规的网站都会提供MD5或类似的散列码,供下载后校验,以防止下载被篡改的文件(有可能包含病毒或恶意代码等) ◆ 网络银行或者手机银行的U盾或者电子证书等 ◆ 区域链以及数字货币等 ◆ ssh…

    2023年4月2日
    00
  • Python工具箱系列(二十四)

    不管多少人黑微软,微软出品的大多数产品都能够深入人心,成为精品。在数据库领域,微软为专业人士提供SQL Server(简称mssql)。为日常办公人士提供Access与Excel这两款数据存储与分析的神器。 SQL Server是微软在数据库领域打造的旗舰产品,使用起来安全、稳定、可靠,并且对于SQL语言的语法与特性支持的非常好。长期以来由于微软敌视开源运动…

    2023年3月31日
    00
  • Python工具箱系列(十二)

    在计算机世界里只有二进制。唯有人类才会对数据进行类型与价值判断。例如,认为某些文件是文本文件、是WORD/EXCEL文件或者是图片。对于加密算法来说也是一样的,加解密算法处理的只是字节流,根本不关心所谓的文件类型。对于文件来说,存在以下基本操作: ◆ open ◆ close ◆ read ◆ write ◆ delete 在Unix世界中,更是将文件这一概…

    2023年4月2日
    00
  • Python工具箱系列(十三)

    上文介绍了使用AES算法进行文件加解密的代码。但是如果在代码中写死了(hardcode)文件名,每次要加解密文件都要去改python源代码,显然有些太笨了。为此,可以使用命令行参数来在不改动源代码的情况下,对命令行参数所指定的文件进行加/解密操作。也可以指定加解密后输出的文件名称,以方便使用。 我们如下约定: python文件名为aeshandler.py …

    Python开发 2023年4月2日
    00
  • Python工具箱系列(三十)

    PostgreSQL MySQL的口号是“世界上最流行的开源关系型数据库”,而PostgreSQL的Slogan则是“世界上最先进的开源关系型数据库(PostgreSQL: The World’s Most Advanced Open Source Relational Database)”,一看这就是一对老冤家了。这两个口号很好的反映出了两者的形象特质:P…

    python 2023年5月8日
    00
  • Python工具箱系列(二十一)

    准备数据 为了方便准备试验用的数据,建议使用Faker这个库来模拟。Faker是一个Python软件包,可生成伪造数据。无论是需要引导数据库,创建美观的XML文档,填充持久性以进行压力测试,还是匿名化来自生产服务的数据,Faker都能完美实现。 pip install faker 以下代码生成姓名、性别这类最常用的试验数据。 from faker impor…

    Python开发 2023年3月31日
    00
  • Python工具箱系列(二十六)

    ClickHouse(Click Stream,Data WareHouse)是俄罗斯的 Yandex于2016年开源的用于在线分析处理查询(OLAP:Online Analytical Processing)MPP架构的列式存储数据库(DBMS:Database Management System),能够使用 SQL 查询实时生成分析数据报告。特别值得称道…

    Python开发 2023年3月31日
    00
合作推广
合作推广
分享本页
返回顶部