python public_使用Python进行非对称加密

v2-3b12d8ae1b256ed14bd7187f9ad15f12_1440w.jpg?source=172ae18b

在本文中,我们将为非对称密码实现Python实现,也称为公钥密码。讨论的算法将是使用公钥和私钥对进行RSA加密和解密以及ECC密钥交换。本文本身并没有解释上述算法,而是使用各种Python库为这些算法提供了Python实现。该Github存储库中将提供本文中使用的所有代码。

RSA(Rivest-Shamir-Adleman)

RSA是包含两个密钥的公共密钥加密,一个是公开密钥,可用于Internet上的所有用户,另一个是私有密钥,只有授权人员才能使用。RSA已用于加密/解密,数字签名,密钥交换。在这里,我们将实现基于RSA的加密和解密。此外,我们将生成公钥和私钥,并将它们存储在单独的文件中,然后再从这些文件导入以进行加密和解密。

我们需要安装一个名为“ PyCryptodome”的Python包才能使用RSA。

pip3 install pycryptodome

让我们看看RSA导入必要的模块

#RSA_cryptography.py


首先,我们导入必要的软件包。

#Importing necessary modules
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
from binascii import hexlify

“ PKCS1_OAEP”是一种基于RSA的密码,使用OAEP(最佳非对称加密填充)填充来为加密带来不确定性和更高的安全性。稍后,我们导入“ RSA”以生成公钥-私钥对。我们导入“ binascii”模块以获取“ hexlify”功能,以将加密的密码转换为十六进制格式。 定义要加密的消息后,我们使用RSA类的“ generate()”函数生成一个长度为1024位的随机私钥。在这里,“ generate()”函数的length参数为1024。

#Generating private key (RsaKey object) of key length of 1024 bits
private_key = RSA.generate(1024)
#Generating the public key (RsaKey object) from the private key
public_key = private_key.publickey()
print(type(private_key), type(public_key))

打印以下输出。

<class'Crypto.PublicKey.RSA.RsaKey'>
<class'Crypto.PublicKey.RSA.RsaKey'>

#将RsaKey对象转换为字符串

private_pem = private_key.export_key()。decode()
public_pem = public_key.export_key()。decode()
print(type(private_pem),type(public_pem))
print(private_pem)
print(public_pem)

上面的代码显示以下内容。

<class'str'> <class'str'>----- BEGIN RSA私钥----- 
MIICXAIBAAKBgQDZuDyT9z04e9GIvc / vlXc6OeQX5pJwZBX71 + 3etKTREiRQEEtz 
VOYEMmHOguytyfTBBxZn9ANioobj2QzAgxyDHfYAUTy2vCUtzcE5XLITxwCg4EWw 
zy1IaMuup48s2JIxYJysbqczNo4LfWUcWMc4B7mWYNUvnRlY5zAlXWX5lwIDAQAB 
AoGALgksWfcpzUM1I45LJPQ8QSYTilA5P6WSFm3qgLA + t2x4HCvN4GWfu1xx3OpH 
JFozNAuNG873VkhacFwpO52djeHUvM8lm / N + lkH6sh7uKJVu5h + KFqfdAsnX9HhW 
byGpz0jd / 4lteACM7pxRzd1qju9KIbSFNbOgb + qRfNscpL0CQQDb38Wnhwx3viTE 
EoZLpn / q6IYYO7OIvLX / ZcVVMqlgjNEoTDbmFN + u8GZq5Rw1YWD4830 / swciB7Bv 
nTfxVr9FAkEA / X3YiFHgefwDH // jx4 + LaAPBNmpv7JSQskNn6F64w4iWLbSDxNU2 
OIWK9tZOdoDeswzofDhGvmc6Sh780XGFKwJBAKleV0 / z / IukoYeTyXUuvWyDTwAN 
xP84dm1UxMwbKVPhRSBojQV4A4C
8ydbDq7PacbFWE4yy4xG + y7twuYKYsYC4MbBOujjco7iZqGtnM2yyT6U + xJz21Ye 
6QkPynj25fiBFSNBxOsCQAWN4XlO2X2p / v1cjh5u9GdHItbqnQc8PVvJR4MzFLqe 
K7dMLOhYWnEWs04lPsvPIqQ3e5Rg2oVQRWuvIMyZ6wM = 
----- END RSA私钥---------- BEGIN PUBLIC KEY ----- 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZuDyT9z04e9GIvc / vlXc6OeQX 
5pJwZBX71 + 3etKTREiRQEEtzVOYEMmHOguytyfTBBxZn9ANioobj2QzAgxyDHfYA 
UTy2vCUtzcE5XLITxwCg4EWwzy1IaMuup48s2JIxYJysbqczNo4LfWUcWMc4B7mW 
YNUvnRlY5zAlXWX5lwIDAQAB 
----- END PUBLIC KEY -----

然后,我们使用“ RsaKey”对象上的“ export_key()”方法将“ RsaKey”对象转换为字节对象,并将其解码为字符串对象,以写入外部文件以保存密钥。

#将私钥和公钥以

open('private_pem.pem','w')作为pr 
    写下'pem'文件:pr.write(private_pem)
以open('public_pem.pem','w')作为pu :
    pu.write(public_pem)

由于现在密钥为字符串格式,因此我们打开(创建)两个名为“ private_pem.pem”和“ public_pem.pem”的文件,以分别以“ .pem”格式保存私钥和公钥。

通过读取文件并使用'RSA'类的'import_key()'函数,我们可以将密钥导入回其原始的'RsaKey'对象。现在,变量“ pr_key”包含私钥“ RsaKey”对象,而“ pu_key”包含公钥“ RsaKey”对象。

#导入文件中的密钥,将其转换为RsaKey对象    
pr_key = RSA.import_key(open('private_pem.pem','r')。read())
pu_key = RSA.import_key(open('public_pem.pem',' r')。read())
print(type(pr_key),type(pu_key))

上面的代码片段输出以下输出。

<class'Crypto.PublicKey.RSA.RsaKey'> 
<class'Crypto.PublicKey.RSA.RsaKey'>

现在,我们进入加密部分。

#使用公开密钥实例化PKCS1_OAEP对象以进行加密
cipher = PKCS1_OAEP.new(key = pu_key)
#使用PKCS1_OAEP对象对消息进行加密
cipher_text = cipher.encrypt(message)
print(十六进制(cipher_text))

我们首先通过接受自变量公钥“ pu_key”从“ PKCS1_OAEP.new()”实例化一个对象,以便使用接收方的公钥对消息进行加密,然后接收方可以使用其私钥对加密的消息进行解密键。

我们通过使用“ encrypt()”方法将消息作为参数来加密消息。以下生成的加密消息。

b'779c998d2ca1e150fc8006977cd8b7d86f090067df805b1438bf75dcd3f5b1e33088e84675f5022371dd59266e75690deed2d98fa76261ce7496f5870f0dea47e86379153788f377e3f1943cd49d20ab938f2fdea3460cc7abeb1b13fcd64a582aca04bfe9f94e76f64ba4faeea417efcd1acdb9e5c8ed68e5be08ff37a4392a”

使用接收者的公钥对消息加密后,发送者已将加密的消息发送给接收者。因此,接收者可以使用其自己的私钥解密加密的消息。

#使用私钥实例化PKCS1_OAEP对象以进行解密
解密= PKCS1_OAEP.new(key = pr_key)
#使用PKCS1_OAEP对象对消息
解密解密_ 消息= crypto.decrypt(cipher_text)
print(decrypted_message )
对于解密,我们使用私钥作为参数从'PKCS1_OAEP'实例化new()函数。使用'decrypt()'方法,以加密的消息作为参数,我们可以按以下方式获取原始消息。
b“公钥和私钥加密”

椭圆曲线Diffie-Hellman(ECDH)密钥交换

椭圆曲线密码学也用于Diffie-Hellman密钥交换,这使发送方和接收方都可以使用秘密。我们将看到如何用Python完成ECDH。在这里,我们有两个用户,Alice和Bob。在它们之间,他们希望拥有一个公共密钥,以便以后可以将此共享公共密钥用于对称密码学。

在ECDH中,Alice和Bob都将具有公钥-私钥对。我们需要按如下方式安装“ tinyec”库。

pip3 install registry

让我们来看看ECDH的作用,我们将在后面解释这些步骤。

#ECDH_key_exchange.py#
从tinyec导入注册表
导入机密导入必要的模块#从注册表
曲线= registry.get_curve('brainpoolP256r1')获取'brainpoolP256r1'曲线#生成Alice的私有
alice_privatekey = secrets.randbelow(curve.field.n)
print(“ Alice的私有密钥:”,alice_privatekey)#生成鲍勃的私钥
bob_privatekey = secrets.randbelow(curve.field.n)
print(“鲍勃的私钥:”,bob_privatekey)#从她的私钥和生成器点生成Alice的公钥
alice_publickey = alice_privatekey * curve.g 
print(“ Alice's public key:”,alice_publickey)#从他的私钥和生成器点生成Bob的公钥
bob_publickey = bob_privatekey * curve.g 
print(“ Bob的公钥:”,bob_publickey)#与Alice共享的密钥
alice_sharedkey = alice_privatekey * bob_publickey 
print(“ Alice的共享密钥:”,alice_sharedkey)#与Bob的共享密钥
bob_sharedkey = bob_privatekey * alice_publickey 
print(“ Bob的共享密钥:”,bob_sharedkey)尝试:
    alice_sharedkey == bob_sharedkey 
    print(“共享的秘密密钥相互匹配”),
除了:
    print(“共享的秘密密钥彼此不匹配”)
我们首先导入必要的模块。
#

从tinyec导入注册表

导入机密导入必要的模块

我们从“ tinyec”和“ secrets”模块导入“ registry”模块,分别获得曲线和随机整数。

现在,我们使用函数“ get_curve()”导入名为“ brainpoolP256r1”的曲线,并以字符串格式作为参数的曲线名称。

#从注册表
曲线= registry.get_curve('brainpoolP256r1')获取'brainpoolP256r1'曲线
我们将使用'secrets'模块的'randbelow()'函数为用户Alice和Bob创建私钥。
#生成Alice的私有
alice_privatekey = secrets.randbelow(curve.field.n)
print(“ Alice的私有密钥:”,alice_privatekey)#生成鲍勃的私钥
bob_privatekey = secrets.randbelow(curve.field.n)
print(“鲍勃的私钥:”,bob_privatekey)

'randbelow()'函数输出范围为[0,curve.field.n)的随机整数,其中'curve.field.n'是曲线的阶数,即所有EC(椭圆形)的总数-曲线)点在曲线上。爱丽丝和鲍勃的私钥如下。

爱丽丝的私钥:38500719669286353616585652767262688968802496611074929227872521733513716284400

鲍勃的私钥:13937276440043839704627988098424951220925508343680833021803996326222354023633

为了便于说明,我们将爱丽丝的私钥设为“ a”,鲍勃的私钥设为“ b”

现在,让我们计算各个用户的公钥。

#从她的私钥和生成器点生成Alice的公钥
alice_publickey = alice_privatekey * curve.g 
print(“ Alice's public key:”,alice_publickey)#从他的私钥和生成器点生成Bob的公钥
bob_publickey = bob_privatekey * curve.g 
print(“ Bob的公钥:”,bob_publickey)

通过将私钥乘以生成器点“ G”来生成ECC中的公钥。我们从“ curve.g”得到“ G”。计算如下。

  1. a * G =爱丽丝的公钥
  2. b * G =鲍勃的公钥

让我们如下计算共享密钥。

#与Alice共享的密钥
alice_sharedkey = alice_privatekey * bob_publickey 
print(“ Alice的共享密钥:”,alice_sharedkey)#与Bob的共享密钥
bob_sharedkey = bob_privatekey * alice_publickey 
print(“ Bob的共享密钥:”,bob_sharedkey)
  1. 爱丽丝的共享密钥= a * b * G(爱丽丝的私有密钥'a',乘以鲍勃的公钥'b * G')
  2. 鲍勃的共享密钥= b * a * G(鲍勃的私钥“ b”乘以爱丽丝的公钥“ a * G”)

那就是'a * b * G'='b * a * G,乘法的关联性质。

最后,我们确保两个共享密钥相等。

尝试:

    alice_sharedkey == bob_sharedkey 
    print(“共享的秘密密钥相互匹配”),

除了:

    print(“共享的秘密密钥彼此不匹配”)

将结果打印为

Shared secret keys match each other

通过使用ECDH,我们可以在授权用户之间共享密钥,并且通过共享密钥,我们可以使用对称加密算法(例如AES,ChaCha20-Poly1305)对数据/消息进行加密和解密。在这里,我们将看到如何从共享密钥中导出密钥。共享密钥由椭圆曲线方程的“ x”,“ y”,“ a”,“ b”和“ p”组成,并且所有组成部分都是整数。

#椭圆曲线方程

y ** 2≡x ** 3 + a * x + b(mod p)

我们必须从中删除“ x”和“ y”部分。为简单起见,我们将从SHA3哈希函数中得出最终的秘密密钥。因此,在此我们将不显示带有最终密钥的对称加密/解密。

我们需要访问共享密钥的“ x”和“ y”组件。由于这些组件是整数,因此我们必须使用“ int”类的“ to_bytes()”函数将其转换为二进制。在这里,我们使用Alice的共享密钥,因为Alice和Bob的共享密钥相等。有三个论点,

  1. 要转换为字节的整数。
  2. 输出的长度(以字节为单位)。
  3. 第三个参数用于大端或小端格式。在这里,我们使用了大端格式。

输出密钥如下。

b'5182c0949c453f4ede34ed81e066cadfa0f4119f6efc6e5c13a18c3810f1898b'

使用此密钥,我们可以进行对称加密/解密。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值