摘要:
本文深入探讨了编解码、加解密及哈希算法的原理、应用。编解码是实现信息有效传输和处理的关键技术,加解密则是保障信息安全的重要手段,而哈希算法在数据完整性和身份验证等方面发挥着不可替代的作用。文章分析了这些算法的基本原理、应用场景以及面临的安全挑战,并提出了相应的改进建议。
一、引言
随着信息技术的快速发展,数据的传输、存储和处理变得日益重要。编解码、加解密及哈希算法作为信息处理领域的核心技术,对于保障信息安全和提高数据处理效率具有重要意义。本文旨在全面阐述这些算法的原理、应用,以期为相关领域的研究和实践提供参考。
二、编解码算法
编解码算法主要用于数据的压缩和解压缩,以减少数据传输和存储的空间占用。这些算法通过不同的方式对数据进行编码和解码,以实现数据的有效传输和处理。在实际应用中,编解码算法广泛应用于图像处理、音频压缩、视频压缩等领域,为多媒体信息的传输和存储提供了有力支持。
三、加解密算法
加解密算法是保障信息安全的重要手段,通过对数据进行加密和解密,防止未经授权的访问和篡改。常见的加解密算法包括对称加密算法(如AES、DES)、非对称加密算法(如RSA、ECC)以及哈希加密算法(如SHA-256、MD5)等。这些算法各有特点,适用于不同的应用场景。对称加密算法具有加解密速度快、资源消耗少的优点,适用于大量数据的加密处理;非对称加密算法则具有更高的安全性,适用于密钥管理和数字签名等场景;哈希加密算法则主要用于数据的完整性校验和身份验证。
四、哈希算法
哈希算法是一种将任意长度的数据映射为固定长度哈希值的算法。哈希值具有唯一性和不可逆性,因此哈希算法在数据完整性和身份验证等方面具有广泛应用。常见的哈希算法包括SHA-256、MD5等。这些算法通过计算数据的哈希值,可以快速验证数据的完整性和真实性,防止数据被篡改或伪造。
五、安全性研究
尽管编解码、加解密及哈希算法在保障信息安全和提高数据处理效率方面发挥了重要作用,但它们也面临着各种安全挑战。例如,加解密算法可能受到暴力破解、中间人攻击等威胁;哈希算法可能受到碰撞攻击等挑战。因此,对这些算法的安全性进行深入研究,提出有效的安全防护措施,具有重要的现实意义。
六、结论与展望
编解码、加解密及哈希算法作为信息处理领域的核心技术,对于保障信息安全和提高数据处理效率具有重要意义。本文对这些算法的原理、应用及其安全性进行了全面阐述,并提出了相应的改进建议。未来,随着信息技术的不断发展,这些算法将面临更多的挑战和机遇。我们将继续关注相关领域的研究进展,为信息安全和数据处理技术的发展做出更大的贡献。
七、实践应用
编解码
Base64编码和解码
Python代码:
#Base64编码和解码 import base64 # 原始数据 data = "Hello, World!" # 编码 encoded_data = base64.b64encode(data.encode()) print("Encoded: ", encoded_data) # 解码 decoded_data = base64.b64decode(encoded_data).decode() print("Decoded: ", decoded_data)
执行结果:
Encoded: b'SGVsbG8sIFdvcmxkIQ==' Decoded: Hello, World!
Hex编码和解码
因为无法用可见字符表示二进制文件。比较常用的一种方式是使用Hex编码进行表示。本文后面内容无特殊情况,都会使用Hex编码表示二进制数据。
Python代码:
#Hex编码和解码 # 原始数据 data = "Hello, World!" # 编码 encoded_data = data.encode().hex() print("Encoded: ", encoded_data) # 解码 decoded_data = bytes.fromhex(encoded_data).decode() print("Decoded: ", decoded_data)
执行结果:
Encoded: 48656c6c6f2c20576f726c6421 Decoded: Hello, World!
ASN.1编码和解码
DER (Distinguished Encoding Rules), BER (Basic Encoding Rules) 和 TLV (Type-Length-Value) 都是ASN.1 (Abstract Syntax Notation One) 编码规则的一部分,用于数据的序列化和反序列化。
-
TLV:Type-Length-Value 是一种编码结构,用于表示一个数据项。Type 表示数据类型,Length 表示数据长度,Value 是实际的数据值。
-
BER:Basic Encoding Rules 是一种ASN.1编码规则,它使用TLV结构来编码数据。BER提供了一种灵活的编码方式,允许数据项有多种可能的编码形式。
-
DER:Distinguished Encoding Rules 是BER的一个子集,它规定了数据项的唯一编码形式。这意味着,对于同一份数据,DER总是产生相同的编码结果。这对于需要比较编码结果的应用(如数字签名)来说非常有用。
总的来说,TLV是一种编码结构,BER和DER是使用这种结构的编码规则。BER提供了编码的灵活性,而DER则提供了编码的一致性。除了DER(Distinguished Encoding Rules),还有一些其他的BER(Basic Encoding Rules)子集,包括:
-
CER(Canonical Encoding Rules):CER是为了处理大型数据结构而设计的,特别是那些可能无法在一个计算机系统的内存中完全存储的数据结构。CER规定了一种确定的编码方式,使得编码结果可以分块处理。
-
PER(Packed Encoding Rules):PER是为了提供一种紧凑的、高效的编码方式而设计的。PER可以将ASN.1定义的数据结构编码为非常小的字节串,这对于带宽有限的环境(如无线通信)非常有用。(C语言)
-
XER(XML Encoding Rules):XER将ASN.1定义的数据结构编码为XML文档,这使得编码结果可以被人类读取和编辑,也可以被XML处理工具处理。(Java语言)
python代码:
#ASN.1编码和解码 from pyasn1.type import univ from pyasn1.codec.der.encoder import encode as der_encode from pyasn1.codec.der.decoder import decode as der_decode from pyasn1.codec.cer.encoder import encode as cer_encode from pyasn1.codec.cer.decoder import decode as cer_decode # 创建一个ASN.1数据结构 data = univ.Sequence() data.setComponentByPosition(0, univ.Integer(123)) data.setComponentByPosition(1, univ.OctetString('abc')) # DER编码 der_encoded_data = der_encode(data) der_encoded_data_hex = der_encoded_data.hex() print("DER Encoded: ", der_encoded_data_hex) # DER解码 decoded_data, _ = der_decode(der_encoded_data, asn1Spec=univ.Sequence()) print("DER Decoded: ", decoded_data.prettyPrint()) # CER编码 cer_encoded_data = cer_encode(data) cer_encoded_data_hex = cer_encoded_data.hex() print("CER Encoded: ", cer_encoded_data_hex) # CER解码 decoded_data, _ = cer_decode(cer_encoded_data, asn1Spec=univ.Sequence()) print("CER Decoded: ", decoded_data.prettyPrint())
执行结果:
DER Encoded: 300802017b0403616263 DER Decoded: Sequence: field-0=123 field-1=abc CER Encoded: 308002017b04036162630000 CER Decoded: Sequence: field-0=123 field-1=abc
对称加密算法
对称加密是一种加密方法,它使用同一个密钥进行加密和解密操作。这意味着,加密和解密的密钥是相同的,也就是说,发送方和接收方必须共享同一个密钥。
对称加密的优点是速度快,适合于大量数据的加密。常见的对称加密算法包括AES(高级加密标准)、DES(数据加密标准)、3DES(三重数据加密算法)和Blowfish、RC4等。
关于填充pad
在PKCS7填充方案中,填充的字节值等于填充的长度。例如,如果需要填充10个字节,那么填充的内容就是10个0x0A
(十进制的10等于十六进制的0A)。
如果数据的长度已经是块大小的倍数,那么会添加一个新的块,这个块的所有字节都是块的大小。例如,如果块的大小是16字节,那么添加的新块的所有字节都是0x10
(十进制的16等于十六进制的10)。
所以,填充的内容取决于需要填充的字节的数量。如果需要填充n个字节,那么填充的内容就是n个0xnn
。
关于块密码工作模式
块密码的工作模式定义了如何将块密码应用于数据块以进行加密和解密。以下是几种常见的块密码工作模式:
-
电子密码本模式(ECB,Electronic Codebook):每个数据块独立加密。这是最简单的模式,但也最不安全,因为相同的明文块会被加密为相同的密文块,这可能会暴露出模式。
-
密码分组链接模式(CBC,Cipher Block Chaining):每个明文块在加密前与前一个密文块进行异或操作。这解决了ECB模式的问题,因为即使两个明文块相同,它们的密文块也会不同。
-
计数器模式(CTR,Counter):这种模式将一个计数器的值加密,然后将结果与明文块进行异或操作以得到密文块。计数器对于每个块都会增加。这种模式的优点是可以并行加密和解密。
-
密码反馈模式(CFB,Cipher Feedback):这种模式将前一个密文块加密,然后将结果与当前明文块进行异或操作以得到当前密文块。
-
输出反馈模式(OFB,Output Feedback):这种模式与CFB类似,但是异或操作是使用加密的前一个块(而不是前一个密文块)。
每种模式都有其优点和缺点,适用于不同的场景。在选择工作模式时,需要考虑到数据的性质、安全需求和性能需求。
DES加解密
⚠️由于计算性能的提高,DES加密已经不再安全。这里仅做参考。
python代码:
#DES加解密 from Crypto.Cipher import DES from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytes # DES key must be exactly 8 bytes long. key = b'8bytekey' def des_encrypt(plain_text): cipher = DES.new(key, DES.MODE_ECB) padded_text = pad(plain_text, DES.block_size) cipher_text = cipher.encrypt(padded_text) return cipher_text def des_decrypt(cipher_text): cipher = DES.new(key, DES.MODE_ECB) plain_text = unpad(cipher.decrypt(cipher_text), DES.block_size) return plain_text # Test data = b'This is a test.' cipher_text = des_encrypt(data) cipher_text_hex = cipher_text.hex() print('Cipher text:', cipher_text_hex) plain_text = des_decrypt(cipher_text) print('Plain text:', plain_text)
执行结果:
Cipher text: bd19aebe536f0eabb79cf45426475dcb Plain text: b'This is a test.
3DES加解密
python代码:
#3DES ECB加解密 from Crypto.Cipher import DES3 from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytes # 3DES密钥长度必须是16或24字节 key = get_random_bytes(16) # 创建一个新的3DES cipher对象 cipher = DES3.new(key, DES3.MODE_ECB) # 原始数据 data = b"This is a test." # 使用3DES cipher对象加密数据 ciphertext = cipher.encrypt(pad(data, DES3.block_size)) cipher_text_hex = ciphertext.hex() print("Ciphertext:", cipher_text_hex) # 创建一个新的3DES cipher对象用于解密 cipher_dec = DES3.new(key, DES3.MODE_ECB) # 使用3DES cipher对象解密数据 plaintext = unpad(cipher_dec.decrypt(ciphertext), DES3.block_size) print("Plaintext:", plaintext) ############################################################################################ #3DES CBC加解密 # 3DES密钥长度必须是16或24字节 key = get_random_bytes(16) # 初始化向量长度必须是8字节 iv = get_random_bytes(8) # 创建一个新的3DES cipher对象,使用CBC模式 cipher = DES3.new(key, DES3.MODE_CBC, iv=iv) # 原始数据 data = b"This is a test." # 使用3DES cipher对象加密数据 ciphertext = cipher.encrypt(pad(data, DES3.block_size)) ciphertext_hex = ciphertext.hex() print("CBC Ciphertext:", ciphertext_hex) # 创建一个新的3DES cipher对象用于解密,使用CBC模式 cipher_dec = DES3.new(key, DES3.MODE_CBC, iv=iv) # 使用3DES cipher对象解密数据 plaintext = unpad(cipher_dec.decrypt(ciphertext), DES3.block_size) print("CBC Plaintext:", plaintext) ############################################################################################ #3DES CFB加解密 from Crypto.Cipher import DES3 from Crypto.Random import get_random_bytes # 3DES密钥长度必须是16或24字节 key = get_random_bytes(16) # 初始化向量长度必须是8字节 iv = get_random_bytes(8) # 创建一个新的3DES cipher对象,使用CFB模式 cipher = DES3.new(key, DES3.MODE_CFB, iv=iv) # 原始数据 data = b"This is a test." # 使用3DES cipher对象加密数据 ciphertext = cipher.encrypt(data) cipher_text_hex = ciphertext.hex() print("CFB Ciphertext:", cipher_text_hex) # 创建一个新的3DES cipher对象用于解密,使用CFB模式 cipher_dec = DES3.new(key, DES3.MODE_CFB, iv=iv) # 使用3DES cipher对象解密数据 plaintext = cipher_dec.decrypt(ciphertext) print("CFB Plaintext:", plaintext)
执行结果:
Ciphertext: 5941e6a4e4c25f519aac7db979c11a8c Plaintext: b'This is a test.' CBC Ciphertext: da96a0a523640ccf725ca5f1b9fa3e43 CBC Plaintext: b'This is a test.' CFB Ciphertext: 92c8ee163ba0d47ee541676b38e848 CFB Plaintext: b'This is a test.'
AES加解密
python代码:
#AES加解密 from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytes # AES密钥长度可以是16(AES128)、24(AES192)或32(AES256)字节 key = get_random_bytes(32) # 初始化向量长度必须是16字节 iv = get_random_bytes(16) # 创建一个新的AES cipher对象,使用CBC模式 cipher = AES.new(key, AES.MODE_CBC, iv=iv) # 原始数据 data = b"This is a test." # 使用AES cipher对象加密数据 ciphertext = cipher.encrypt(pad(data, AES.block_size)) cipher_text_hex = ciphertext.hex() print("Ciphertext:", cipher_text_hex) # 创建一个新的AES cipher对象用于解密,使用CBC模式 cipher_dec = AES.new(key, AES.MODE_CBC, iv=iv) # 使用AES cipher对象解密数据 plaintext = unpad(cipher_dec.decrypt(ciphertext), AES.block_size) print("Plaintext:", plaintext)
执行结果:
Ciphertext: 7590c65c4396b2006770f795896dd7ff Plaintext: b'This is a test.'
Blowfish加解密
python代码:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend # 创建一个 Blowfish 密钥 key = b"my secret key" # 创建一个 Blowfish cipher 对象 cipher = Cipher(algorithms.Blowfish(key), modes.ECB(), backend=default_backend()) # 创建一个加密器对象 encryptor = cipher.encryptor() # 加密一些数据 plaintext = b"the data(shoudbe24bytes)" ciphertext = encryptor.update(plaintext.ljust(24, b'\0')) + encryptor.finalize() cipher_text_hex = ciphertext.hex() # 创建一个解密器对象 decryptor = cipher.decryptor() # 解密数据 decrypted_text = decryptor.update(ciphertext) + decryptor.finalize() print("Original text:", plaintext) print("Encrypted text:", cipher_text_hex) print("Decrypted text:", decrypted_text.strip())
执行结果:
Original text: b'the data(shoudbe24bytes)' Encrypted text: bac4c9c3bbc05b083b595946b89f38c86e03939b279bebac Decrypted text: b'the data(shoudbe24bytes)'
RC4加解密
python代码:
#RC4算法 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend # 密钥 key = b'secret_key' # 创建一个新的RC4 cipher对象 cipher = Cipher(algorithms.ARC4(key), mode=None, backend=default_backend()) # 加密 encryptor = cipher.encryptor() ciphertext = encryptor.update(b'message') cipher_text_hex = ciphertext.hex() # 解密 decryptor = cipher.decryptor() plaintext = decryptor.update(ciphertext) print('Ciphertext:', cipher_text_hex) print('Plaintext:', plaintext)
执行结果:
Ciphertext: 2e5ae8d2a1328e Plaintext: b'message'
哈希算法及其它相关算法
哈希算法
哈希算法,如MD5或SHA系列,被设计用于生成数据的唯一表示(尽管存在理论上的碰撞可能性)。这些表示通常用于数据的快速查找,密码存储,数字签名等。
而CRC算法主要用于检测数据是否被更改。它通过对数据进行特定的数学运算,生成一个校验和。然后可以通过比较这个校验和和原始数据的校验和,来检测数据是否被更改。
以下是一些常用的Hash算法:
MD5:MD5是一种广泛使用的加密哈希函数,产生一个128位(16字节)的哈希值,通常用32字符的十六进制数表示。
SHA-1:SHA-1是安全哈希算法系列的一种,产生一个160位(20字节)的哈希值。它比MD5更安全,但在现代计算能力下,SHA-1的安全性也已经被质疑。
SHA-256:SHA-256是SHA-2哈希函数家族的一员,产生一个256位(32字节)的哈希值。SHA-256比SHA-1更安全,是许多安全协议和标准的首选。
SHA-3:SHA-3是最新的安全哈希算法标准,其安全性和效率都比SHA-2更高。
BLAKE2:BLAKE2是一种加密哈希函数,旨在提供比MD5,SHA-1,SHA-2,SHA-3更高的性能和安全性。
python代码:
import hashlib data = "Hello, World!" # MD5 md5_hash = hashlib.md5() md5_hash.update(data.encode('utf-8')) print("MD5: ", md5_hash.hexdigest()) # SHA-1 sha1_hash = hashlib.sha1() sha1_hash.update(data.encode('utf-8')) print("SHA-1: ", sha1_hash.hexdigest()) # SHA-256 sha256_hash = hashlib.sha256() sha256_hash.update(data.encode('utf-8')) print("SHA-256: ", sha256_hash.hexdigest()) # SHA-3 (Python 3.6+) sha3_hash = hashlib.sha3_256() sha3_hash.update(data.encode('utf-8')) print("SHA-3: ", sha3_hash.hexdigest()) # BLAKE2 (Python 3.6+) blake2_hash = hashlib.blake2s() blake2_hash.update(data.encode('utf-8')) print("BLAKE2: ", blake2_hash.hexdigest())
执行结果:
MD5: 65a8e27d8879283831b664bd8b7f0ad4 SHA-1: 0a0a9f2a6772942557ab5355d76af442f8f65e01 SHA-256: dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f SHA-3: 1af17a664e3fa8e419b8ba05c2a173169df76162a5a286e0c405b460d478f7ef BLAKE2: ec9db904d636ef61f1421b2ba47112a4fa6b8964fd4a0a514834455c21df7812
CRC(循环冗余校验)
CRC(循环冗余校验)算法通常被用于检测数据传输或存储过程中的错误,而不是用于生成唯一的数据表示,所以它通常不被归类为哈希算法。虽然CRC和哈希算法在某些方面有相似之处,但它们的目标和用途是不同的。
python代码:
import binascii def calculate_crc32(data): return binascii.crc32(data.encode()) data = "Hello, World!" crc32 = calculate_crc32(data) print(f"CRC32 of '{data}' is: {crc32}")
执行结果:
CRC32 of 'Hello, World!' is: 3964322768
Bcrypt算法
Bcrypt是一种用于密码哈希的加密算法。它的特点是使用了一个基于Blowfish的密钥派生函数,并且可以包含一个盐值,以防止彩虹表攻击。Bcrypt每次的结果是不同的,但都可以通过函数进行校验。Bcrypt的主要优点可以控制算法的计算复杂度(通过所谓的"cost"因子),这意味着即使随着计算能力的提高,你也可以保持密码哈希的强度。
python代码:
#Bcrypt算法 import bcrypt # Generate a random salt salt = bcrypt.gensalt() # Hash a password1 password = b"my password" hashed_password1 = bcrypt.hashpw(password, salt) print(f"Hashed password1: {hashed_password1}") # Hash a password2 salt = bcrypt.gensalt() hashed_password2 = bcrypt.hashpw(password, salt) print(f"Hashed password2: {hashed_password2}") # Verify a password if bcrypt.checkpw(password, hashed_password1): print("Password1 is correct") else: print("Password1 is incorrect") if bcrypt.checkpw(password, hashed_password2): print("Password2 is correct") else: print("Password2 is incorrect")
执行结果:
Hashed password1: b'$2b$12$j3CDNGS/QR7sVyZ1R8IejuCqGxAFiebKuNAj7iLHKLrQ.wf0PQeoq' Hashed password2: b'$2b$12$i9RTdjVRo3kgLSzoMkYVUOCnp4Po2ox4sl7tLDYPdZ1wp4k5TriQu' Password1 is correct Password2 is correct
非对称算法
RSA加解密
RSA算法使用公钥进行加密,使用私钥进行解密
配置RSA加密和解密中使用的填充方案,具体来说是最优非对称加密填充(Optimal Asymmetric Encryption Padding,简称OAEP)。
OAEP是一种用于非对称密钥加密的填充形式,它允许在系统中引入额外的随机性,从而增强加密的安全性。它通常与RSA加密一起使用以提高其安全性。
在这段代码中,padding.OAEP
被初始化并带有三个参数:
-
mgf
:这代表掩码生成函数(Mask Generation Function)。这是填充过程中使用的一种函数。在这里,使用了padding.MGF1
,这是OAEP常用的选择。它被配置为使用SHA256作为哈希函数。 -
algorithm
:这是加密过程中使用的哈希函数。在这里,使用了SHA256,这是因为它在安全性和性能之间取得了平衡的一个常用选择。 -
label
:这是一个可选参数,可以用来将标签与消息关联。在这种情况下,它被设置为None
,意味着没有使用标签。
这种填充配置通常作为RSA加密和解密函数的参数,例如在提供的上下文中的encrypt
函数。该函数接收一个明文消息和一个填充方案作为输入,并返回加密的消息。
python代码:
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization # 生成RSA密钥对 private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend() ) public_key = private_key.public_key() # 将密钥对转换为十六进制格式 private_key_hex = private_key.private_bytes( encoding=serialization.Encoding.DER, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ).hex() public_key_hex = public_key.public_bytes( encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo ).hex() print("Private key: ", private_key_hex) print("Public key: ", public_key_hex) # RSA加密 message = b'secret message' encrypted_message = public_key.encrypt( message, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) print("Encrypted message: ", encrypted_message.hex()) # RSA解密 decrypted_message = private_key.decrypt( encrypted_message, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) print("Decrypted message: ", decrypted_message)
执行结果:
Private key: 308204be020100300d06092a864886f70d0101010500048204a8308204a40201000282010100c8a9bf9838eb39ad911db6524f6de85bda56391ad95f35165c5a3ba2ae6cef4648264e61c91fef589636be58d4d18ebd719dcbbf6002cf937aefc05be611d5957b37c6ad0f2ce2dc5bfbd5b2c4698e36586c44c8804531da2aa351a02df7440bd41d60962494d646ac141f65dafa6853e51c99c2632f3e39f2656eb3ea2af3361b64c06bb9b7a6719b13ea0dfb4b28c4e6cc1edf7622c05244505974c5456c14b3d6ab30245918c8ad16e6fa42818af83b6ba39a690ef26c658424ddfeb33f696c78533fa4ef9d2dd0457ecb9dc0e0b34b8b986140eb82f525a4f99232520a5c70c04629993414a0f510be102988912eecbda75398e6a151e5679e2aeec1a6b502030100010282010100c80e8ce93bde30cbfdc10cb3f562d3653841fc7eeb37039b7e89aba91e9396de903238b53f2aea9a7c70a9c7b0ae18cc8108dc48b97533f48a7d9b5f43fa85e1994e5b72d08d64c463a4a942a895c0662834114380b6fbe3d1dcb015ad9e37263fdce61deaecc4d102e0b109008fe511b77b93447d546d8aa243446275554ad1e3b0cf1eac86e95dddd8ec8a87eb383363b7f4dae65ed3532367a18c51315b12ef2e98a52117ad3c0f90c50982505cafec5709ed8c6893b7c51c8c02ef6930529cd4604f56ac739390c97f8d52b94d54806920c4a1a5c3ac63eacd339a542157d84d5a740910714372a574fe09638af1f0f0189b01f3e8b52d6bf5ae1d845da102818100eb35d6295b0d18d5bc2359e29884212383816f75c5a066eb2389eda90bde9ce897bb2f1cf0e4ee4e83f2319daf70e01cb97fd63e2502993b1b2a2c30376b1941a9af55fa0b4ceefbc8ffe05d8d1e1acf0a3302259ffb9e78ec4b4a0f6e5ff0a80e89a0bbcbdc10af0923de5f1f0b1e0387f02b8ea8d12f1a6998f4a88cc2732902818100da6633fea0e3edde2abe1af3ba7cc65e8ef1ee8a6976f3f0156fed486b9e47977c7b1dd6f55b933a07fe5e4143b2b88fc49c28ce0c454ce47a69a39cd5d236aaaa5e35f682ca4f711870c44b61ab818edde56d6f796b15f7255a1ab6db807e9c0ed94bd6785f261b51df6bb349d69e7437f5f05b8d6d9c66dc22a70a6879b4ad02818100d9ba7a46ca0c33a316873adb71074e8dcb5bf3cb7767661de045fb83f282dd88c97bf2bebd978da98ca6939b3e1e24b73257ce00b4cdd4fe4bc51c267e065bd8d6b481c7f6d1fe9f808eac28ad4ae2d228c4d305f5343c9bff502a7c6255d936184efa451d0ed73ad0212de5ab9ce4e9abda7cd7901a239a3589eb6062fc551102818078beb2965f4b44b264bd2fd77a4e0bba319b8e3f55e99f1a282ff666e8a0dc81e31f8a32d2f9eb1ed5568bb3d782d2c92171189a3a6c82037bae35f7babb7adfc64b49d85d1d0ee8bf1371631fbf9b646a47b2c643c1b1a62f2f6ebf9401a97e0c3394db2137b1b0bf061fdc42c1765f58a50f5afe8910444a069a8585976c0d0281804d228f366f50187b2580469a4a2facfaeab9f1744f10cff14589de1e65a778c65ad4cc2cfb0f6ed2b5c035f91a7e886077e0cc5a48670f7f83c1768f6d40ddac8007de8eab16126b051c98f7b23860fd54984e6551d7f8d8b7bba3c6feb30f8bcd8f60d646bbff0c2a3d28f75859fe6699131ac91e8e46b8939b0f7452373cc0 Public key: 30820122300d06092a864886f70d01010105000382010f003082010a0282010100c8a9bf9838eb39ad911db6524f6de85bda56391ad95f35165c5a3ba2ae6cef4648264e61c91fef589636be58d4d18ebd719dcbbf6002cf937aefc05be611d5957b37c6ad0f2ce2dc5bfbd5b2c4698e36586c44c8804531da2aa351a02df7440bd41d60962494d646ac141f65dafa6853e51c99c2632f3e39f2656eb3ea2af3361b64c06bb9b7a6719b13ea0dfb4b28c4e6cc1edf7622c05244505974c5456c14b3d6ab30245918c8ad16e6fa42818af83b6ba39a690ef26c658424ddfeb33f696c78533fa4ef9d2dd0457ecb9dc0e0b34b8b986140eb82f525a4f99232520a5c70c04629993414a0f510be102988912eecbda75398e6a151e5679e2aeec1a6b50203010001 Encrypted message: 6bc0731c6612fbbea807764836a7471566e36c05a00a29d23d4e706ec82fe9bd4b0f154cc7d96e944b23c044178c4853ae53afcc5e322d8ccecd365111b128107f84452800f6f3572d6f9fd5c017aa5009728bac9452ae0419f5e4c491e094b28e1d5c1aa96ee64094595b3049e5e28da9f50401ab13c17c5844ccca38a935ef627cf112cfcf316efff7defde80a0d5b50aa29e774771d2a7bf5d1e0684530c62969d0da5c6afd1b57128fc94a8a6721565f5c2c1be0aa889bd15eb0b4c155c95176875a5609fcb6da05acdce5fc63a487b4e2a78d6d41ab6fd4d07ed286d8aa69bf73be82403130ff87e8ac2927132e33007df390e0f04fb7d73d99e2f99039 Decrypted message: b'secret message'
RSA签名验证及签名
RSA算法使用私钥钥进行签名,使用公钥进行验证签名
python代码:
from Crypto.PublicKey import RSA from Crypto.Signature import pkcs1_15 from Crypto.Hash import SHA256 # 生成RSA密钥对 key = RSA.generate(1024) public_key = key.publickey() # 原始消息 message = b'Transaction Information' # 使用私钥进行签名 h = SHA256.new(message) signature = pkcs1_15.new(key).sign(h) signature_hex = binascii.hexlify(signature) print('Signature:', signature_hex) # 发送消息和签名 sent_message = message sent_signature = signature # 在接收端... # 解密消息(如果消息被加密的话) # 在这个例子中,我们假设消息没有被加密,所以可以直接使用 received_message = sent_message # 使用公钥验证签名 h2 = SHA256.new(received_message) try: pkcs1_15.new(public_key).verify(h2, sent_signature) print('The signature is valid.') except (ValueError, TypeError): print('The signature is not valid.')
执行结果:
Signature: b'612183aef267d5294b5e7c7d0f8a78a3bec6a5124ae7bb2424952ec13c3951f45ada9f7b7340d1c8169986726191f4f12c203e3ed24c60f22a56aa589f93395c7f97b7bd6725e92dcc2af195b3de01e4cbc7db1898c2fbd4419a62dc5fbcc80a0928a5cdf8c67ca99c5ae80be4bd1cf5a0c97f22f40621632f20918f521a8a2a' The signature is valid.
ECC加解密
python代码:
from ecies.utils import generate_eth_key from ecies import encrypt, decrypt # 生成ECC密钥对 sk = generate_eth_key() pk = sk.public_key print("Private key: ", sk.to_hex()) print("Public key: ", pk.to_hex()) # ECC公钥加密 plaintext = b'secret message' encrypted_message = encrypt(pk.to_hex(), plaintext) encrypted_message_hex = encrypted_message.hex() print("Encrypted message: ", encrypted_message_hex) # ECC私钥解密 decrypted_message = decrypt(sk.to_hex(), encrypted_message) print("Decrypted message: ", decrypted_message.decode())
执行结果:
Private key: 0x3a073f3701e52d3cc08964c3b9a6aaee862e2abf7f23752cfb09da9f8ed7f322 Public key: 0x6d4183f312aa7f29bca36726b2bb0ee9432fbf6f26974495982a89de361233916c427fc428402a93c121ab9d9038e2dbeecc6cefed2340109d4084230de58979 Encrypted message: 0451a22b48798e903d84652bb287eeefff3c3f89b57d7c35d0affded00938fe10777179622640e226e0b7f963fa9534e7b836c008e54651509e326f76d8e259fa8b799a0cb822a5b2ec2b712940a94906159400807255cc2e4e58e2f0da7c4fcf42b6178c442f345f4d32d7f5fd850 Decrypted message: secret message
ECC签名验证及签名
python代码:
#ECC签名和验证 from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ec from cryptography.exceptions import InvalidSignature from cryptography.hazmat.backends import default_backend # 生成ECC密钥对 private_key = ec.generate_private_key(ec.SECP256R1(), default_backend()) public_key = private_key.public_key() # ECC签名 message = b'secret message' signature = private_key.sign( message, ec.ECDSA(hashes.SHA256()) ) signature_hex = signature.hex() print("Signature: ", signature_hex) # 验证签名 try: public_key.verify( signature, message, ec.ECDSA(hashes.SHA256()) ) print("The signature is valid.") except InvalidSignature: print("The signature is invalid.")
执行结果:
Signature: 3045022100a9c93c0d81660974f753f15f291044be223213d7c4c6638a1b76f7254885422d02203d21156c3192fc2a30102f7ff2b6025f061ee830323eb4ab032bea0d05f71a7d The signature is valid.
MAC校验
MAC(Message Authentication Code)算法是一种用于验证消息完整性和身份认证的加密技术。MAC算法需要一个密钥和一个消息作为输入,生成一个固定大小的代码(通常称为MAC)作为输出。MAC可以用来验证消息没有被篡改,并且是由持有密钥的实体发送的。
MAC算法有很多种
-
HMAC:HMAC使用一个加密哈希函数(在你的代码中是SHA256)和一个密钥来生成MAC。HMAC的安全性取决于所使用的哈希函数的安全性。
-
CMAC:CMAC使用一个块密码(在你的代码中是AES)和一个密钥来生成MAC。CMAC的安全性取决于所使用的块密码的安全性。
-
GMAC:Galois Message Authentication Code,是GCM(Galois/Counter Mode)模式中使用的MAC算法,基于块密码。
-
UMAC:Universal Message Authentication Code,是一种基于通用哈希函数的MAC算法。
-
Poly1305:是一种基于一次性密码的MAC算法,通常与ChaCha20流密码一起使用。
-
VMAC:是一种非常快速的MAC算法,基于通用哈希函数。
MAC(Message Authentication Code)和数字签名都是用于验证消息完整性和身份认证的技术,但它们在使用和安全性方面有一些重要的区别:
-
密钥类型:MAC使用的是对称密钥,也就是说,发送者和接收者使用的是同一个密钥。而数字签名使用的是非对称密钥,发送者使用私钥进行签名,接收者使用公钥进行验证。
-
非否认性:数字签名提供了非否认性,这意味着发送者不能否认他们已经发送了消息。这是因为只有发送者才有私钥,所以只有他们才能生成有效的签名。而MAC没有这个特性,因为密钥是共享的。
-
使用场景:由于数字签名提供了非否认性,它们通常用于法律和合同等需要证明身份的场景。而MAC由于计算效率更高,通常用于需要频繁验证消息完整性的场景,如网络通信。
-
性能:由于数字签名使用的是非对称加密,它们通常比使用对称加密的MAC更慢。
总的来说,MAC和数字签名都是用于验证消息完整性和身份认证的重要工具,但它们适用于不同的场景。
python代码:
from cryptography.hazmat.primitives import hashes, hmac, cmac from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 from cryptography.hazmat.primitives.ciphers import algorithms from cryptography.hazmat.backends import default_backend import os # HMAC hmac_key = b'secret_key' h = hmac.HMAC(hmac_key, hashes.SHA256(), backend=default_backend()) h.update(b'message') hmac_final = h.finalize() hmac_final_hex = hmac_final.hex() print("HMAC: ", hmac_final_hex) # CMAC cmac_key = b'sixteen_byte_key' c = cmac.CMAC(algorithms.AES(cmac_key), backend=default_backend()) c.update(b'message') cmac_final = c.finalize() cmac_final_hex = cmac_final.hex() print("CMAC: ", cmac_final_hex) # Poly1305 poly1305_key = ChaCha20Poly1305.generate_key() chacha = ChaCha20Poly1305(poly1305_key) nonce = os.urandom(12) ct = chacha.encrypt(nonce, b'message', None) ct_hex=ct.hex() print("Poly1305: ", ct_hex)
执行结果:
HMAC: ebb8d2ee5dcad6e9d6fc0b606811f9f03036bdd419a364d1a1ce1afa1bea61fd CMAC: 09aa47c7ea9318c1391b222a119e2346 Poly1305: 0f11aa27e51e074e4725ee600fef8e9c4408ef2a288eec