本篇博客仅从区块链的角度介绍加密算法及数字签名,重在使用,至于加密算法的内部原理这里不会详细介绍。

1 对称加密

1.1 定义

  对称加密,指的是信息发送者和接收者通过使用的相同的密钥来完成数据的加密和解密。常用的对称加密算法有:AES、DES、3DES等。

1.2 AES算法

  AES(Advanced Encryption Standard)是目前应用最广泛的加密算法之一。AES算法使用的密钥和数据的长度都是固定的,其中密钥长度可以是128位、192位或256位,数据块长度为128位(这里的位是指bit位,相当于16个字节)。它采用了替代、置换、线性和逻辑运算等步骤进行多轮加密。其Python示例如下:

import base64from Crypto.Cipher import AESfrom Crypto.Random import get_random_bytesfrom Crypto.Util.Padding import pad,unpad#生出16位的随机密钥,同时也用这个密钥作为偏移量key=get_random_bytes(16)iv=key #要传输的数据,data的大小超过AES限定的16位data='今天是2023年06月29日,3天之后Lucy会来看我。'#加密AES_obj=AES.new(key,AES.MODE_CBC,iv)AES_str=AES_obj.encrypt(pad(data.encode('utf-8'),AES.block_size))#对bytes-like对象进行编码并返回bytes对象AES_en_str=base64.b64encode(AES_str) print("加密后的密文:{}".format(AES_en_str))#解密AES_DE_obj=AES.new(key,AES.MODE_CBC,iv)DE_en_str=unpad(AES_DE_obj.decrypt(AES_str),AES_DE_obj.block_size)AES_de_str=DE_en_str.decode()print("解密后的原文:{}".format(AES_de_str))

其结果如下:

加密后的密文:b’ZzLvCA486r8bO3Y5fIbNEUlWaUteS4+Trp4KCIMxaj1mZa6DaGQp70NfK8+759zGl4zS/iKeC5bNlhq1o2EfMQ==’
解密后的原文:今天是2023年06月29日,3天之后Lucy会来看我。

注意,AES中规定的数据块长度位128位,但并意味着AES只能处理长度为128位的数据。只要加密数据的长度为128位的整数倍,AES都可以处理。在上述案例中,data占448位(56个字节),并不是128的整数倍,所以代码里使用pad方法在加密前对data进行填充,使用unpad对解密后得到的原文去除填充。

1.3 对称加密的优缺点

  对称加密算法的优点是算法公开、计算量小、加密速度快、加密效率高。而缺点主要在于密钥安全和密钥管理两方面。

  • 密钥安全:数据发送方和接受方在数据传输之前,需要商定密钥并严格保存密钥。因为一旦密钥泄露,那么加密的信息则会受到攻击。
  • 密钥管理:每对用户都需要使用其他人不知道的独一秘钥,这会使得收、发双方所拥有的钥匙数量巨大,密钥管理会成为双方的负担。

2 非对称加密

2.1 定义

  非对称加密,主要是依据一组唯一性的密钥完成,即公开密钥和私有密钥。两个密钥之间存在数学关联性,信息发送者使用公钥对数据进行加密后,接收者只可以通过对应的私钥进行解密。在非对称加密中,信息收、发者之间无需进行密钥交换。常用的非加密算法主要有:RSA算法、Diffie-Hellman算法等。

2.2 RSA算法

  RSA算法是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的是绝大多数密码攻击。RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却及其困难,因此可以将乘积公开作为加密密钥。其Python示例如下:

from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_OAEP# 生成RSA密钥对key = RSA.generate(2048)private_key = key.export_key()# 获取私钥public_key = key.publickey().export_key()# 获取公钥# 使用公钥加密数据message = b"Hello, World!"cipher_rsa = PKCS1_OAEP.new(RSA.import_key(public_key))encrypted_message = cipher_rsa.encrypt(message)# 使用私钥解密数据cipher_rsa = PKCS1_OAEP.new(RSA.import_key(private_key))decrypted_message = cipher_rsa.decrypt(encrypted_message)print("原始数据:", message)print("解密后数据:", decrypted_message)
2.3 非对称加密的优缺点

  非对称加密具有更高的安全性,信息发送方只需要公开自己的公钥,不需要将私钥传给别人。但这种加密算法的加密和解密需要花费太长时间、速度比较慢,一般只用来对少量数据进行加密的。

3 数字签名

3.1 定义

  数字签名(又称公钥数字签名)是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明(保证了区块链的不可抵赖性)。数字签名是非对称加密技术和数字摘要技术的结合,主要包括两种互补的运算:签名和验证。具体如下:

  • 签名:发送信息的一方首先需要计算信息的摘要,然后利用私钥对这个摘要进行加密计算,并附在信息上一起发送给接收方,这样就完成了签名的过程。
  • 验证:接收方接收到附带签名的消息后,同样需要计算消息的摘要,然后用消息发送方对应的公钥对签名进行验证。

  另外,数字摘要技术可以保证如果消息中的任何一位被篡改了都会产生不同的摘要,那么验证就不会通过,这样就保证了区块链消息的不可篡改性。区块链中一般使用哈希函数来实现计算信息的摘要。常用的哈希函数: SHA-256、SHA-1、SHA-3等。

3.2 具体流程

  数字签名的具体计算流程如下:

  • 生成私钥和公钥:可以使用RSA算法生成公钥钥pk=(e,m)pk=(e,m) pk=(e,m)和私sk=(d,n)钥$$。
  • 签名:假设原文为MM M,使用哈希函数为HH HMM M加密得到哈希值H(M)H(M) H(M)。接着使用私钥生成签名S=H(M ) dmodnS=H(M)^{d} mod\space n S=H(M)dmodn
  • 验证:计算 S emodnS^{e} mod \space n Semodn是否等于H(M)H(M) H(M),若相等则验证通过,否则验证不通过。
3.3 Python实现
import hashlibfrom Cryptodome.PublicKey import RSAfrom Cryptodome.Signature import PKCS1_v1_5from Cryptodome.Hash import SHA256# 生成RSA密钥对key = RSA.generate(2048)private_key = key.export_key()public_key = key.publickey().export_key()# 准备要签名的数据data = "Hello, world!".encode('utf-8')# 使用私钥进行签名private_key = RSA.import_key(private_key)signer = PKCS1_v1_5.new(private_key)signature = signer.sign(SHA256.new(data))# 使用公钥进行验证public_key = RSA.import_key(public_key)verifier = PKCS1_v1_5.new(public_key)verified = verifier.verify(SHA256.new(data), signature)if verified:print("数字签名验证成功")else:print("数字签名验证失败")

注意:上述代码可以在MAC系统上运行(需要使用pip install命令安装pycryptodomex包);而Windows系统中需要使用pip install 安装pycryptodome包,同时上述代码中Cryptodome改成Crypto.

参考文献

  1. https://blog.csdn.net/qq_43427438/article/details/127391033
  2. https://blog.csdn.net/m0_51607907/article/details/123884953