python对称加密与非对称加密_使用Python进行非对称加密

在本文中,我们将为非对称密码实现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

#The message to be encrypted

message = b'Public and Private keys encryption'

#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))

#Converting the RsaKey objects to string

private_pem = private_key.export_key().decode()

public_pem = public_key.export_key().decode()

print(type(private_pem), type(public_pem))

#Writing down the private and public keys to 'pem' files

with open('private_pem.pem', 'w') as pr:

pr.write(private_pem)

with open('public_pem.pem', 'w') as pu:

pu.write(public_pem)

#Importing keys from files, converting it into the RsaKey object

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))

#Instantiating PKCS1_OAEP object with the public key for encryption

cipher = PKCS1_OAEP.new(key=pu_key)

#Encrypting the message with the PKCS1_OAEP object

cipher_text = cipher.encrypt(message)

print(cipher_text)

#Instantiating PKCS1_OAEP object with the private key for decryption

decrypt = PKCS1_OAEP.new(key=pr_key)

#Decrypting the message with the PKCS1_OAEP object

decrypted_message = decrypt.decrypt(cipher_text)

print(decrypted_message)

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

#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))

打印以下输出。

#将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)

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

----- 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))

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

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

#使用公开密钥实例化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”。计算如下。a * G =爱丽丝的公钥

b * G =鲍勃的公钥

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

#与Alice共享的密钥

alice_sharedkey = alice_privatekey * bob_publickey

print(“ Alice的共享密钥:”,alice_sharedkey)#与Bob的共享密钥

bob_sharedkey = bob_privatekey * alice_publickey

print(“ Bob的共享密钥:”,bob_sharedkey)爱丽丝的共享密钥= a * b * G(爱丽丝的私有密钥'a',乘以鲍勃的公钥'b * G')

鲍勃的共享密钥= 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的共享密钥相等。有三个论点,要转换为字节的整数。

输出的长度(以字节为单位)。

第三个参数用于大端或小端格式。在这里,我们使用了大端格式。

输出密钥如下。

b'5182c0949c453f4ede34ed81e066cadfa0f4119f6efc6e5c13a18c3810f1898b'

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值