对称加密(私有密钥加密)
场景:
小明和小红是好朋友,他们经常通过信件交流。为了防止信件内容被别人偷看,他们决定使用一种秘密的“密码本”来加密和解密信件。
人物:
-
小明:发送者
-
小红:接收者
过程:
-
加密:小明和小红共享同一个“密码本”。小明在写信时,使用“密码本”将信件内容转换成密文。
-
传输:小明将密文信件通过邮局寄给小红。
-
解密:小红收到信件后,使用相同的“密码本”将密文转换回原始内容。
优点:
-
速度快:因为使用同一个“密码本”,加密和解密过程非常快。
-
简单:只需要一个“密码本”,操作简单。
缺点:
-
密钥管理复杂:小明和小红必须确保“密码本”不被其他人获取,否则信件内容会被泄露。
常见算法:
-
DES(Data Encryption Standard):采用替换和移位的方法进行加密,密钥长度为56位。
-
3DES(Triple DES):在DES的基础上进行三次加密,相当于将密钥长度加倍,提高了安全性。
-
RC-5:由RSA数据安全公司定义,广泛应用于其产品中。
-
IDEA(International Data Encryption Algorithm):类似于3DES,但采用了不同的加密机制。
-
AES(Advanced Encryption Standard):基于排列和置换运算,是目前最常用的对称加密算法之一。
非对称加密(公开密钥加密)
场景:
小明和小红决定使用一种更安全的方式来通信。他们决定使用“公开信箱”和“私人信箱”来加密和解密信件。
人物:
-
小明:发送者
-
小红:接收者
过程:
-
公开信箱和私人信箱:小红有一个公开信箱(公钥)和一个私人信箱(私钥)。公开信箱可以被任何人看到,但只有小红有私人信箱的钥匙。
-
加密:小明在写信时,使用小红的公开信箱将信件内容转换成密文。
-
传输:小明将密文信件通过邮局寄给小红。
-
解密:小红收到信件后,使用自己的私人信箱钥匙将密文转换回原始内容。
优点:
-
安全性高:即使公开信箱被别人看到,也无法解密信件内容,因为只有小红有私人信箱的钥匙。
-
密钥管理简单:小红只需要保管好自己的私人信箱钥匙,不需要担心密钥的分发问题。
缺点:
-
速度较慢:相比于对称加密,使用公开信箱和私人信箱进行加密和解密的过程较慢。
常见算法:
-
RSA:基于大数分解的数学难题,是目前最常用的非对称加密算法之一。
-
ECC(Elliptic Curve Cryptography):基于椭圆曲线数学,提供了与RSA相当的安全性,但密钥长度更短。
-
DSA(Digital Signature Algorithm):主要用于数字签名,而不是加密。
总结
-
对称加密:就像小明和小红共享一个“密码本”,加密和解密速度快,但密钥管理复杂。
-
非对称加密:就像小红使用公开信箱和私人信箱,安全性高,但加密和解密速度较慢。
应用场景
-
对称加密:适用于需要快速加密和解密的场景,如文件加密、数据库加密等。
-
非对称加密:适用于需要高安全性的场景,如SSL/TLS协议、数字签名、密钥交换等。
实践
AES 对称加密实践(python版)
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.backends import default_backend
from cryptography.fernet import Fernet
import os
import base64
# 生成随机的256位密钥和16字节的偏移量
key = Fernet.generate_key() # 生成一个256位的密钥
iv = os.urandom(16) # 128 bits = 16 bytes
# 确保密钥长度为32字节
key = base64.urlsafe_b64decode(key)
# 打印密钥和偏移量
print(f"密钥 (Base64): {base64.b64encode(key).decode('utf-8')}")
print(f"偏移量 (Base64): {base64.b64encode(iv).decode('utf-8')}")
def encrypt(plaintext, key, iv):
# 使用PKCS7填充
padder = padding.PKCS7(algorithms.AES.block_size).padder()
padded_data = padder.update(plaintext.encode('utf-8')) + padder.finalize()
# 创建AES加密器
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
encryptor = cipher.encryptor()
# 加密数据
ciphertext = encryptor.update(padded_data) + encryptor.finalize()
# 将加密结果编码为Base64
return base64.b64encode(ciphertext).decode('utf-8')
def decrypt(ciphertext_base64, key, iv):
# 解码Base64格式的密文
ciphertext = base64.b64decode(ciphertext_base64)
# 创建AES解密器
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
decryptor = cipher.decryptor()
# 解密数据
padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize()
# 移除PKCS7填充
unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
plaintext = unpadder.update(padded_plaintext) + unpadder.finalize()
return plaintext.decode('utf-8')
# 示例使用
plaintext = "Hello, AES!"
print(f"原始文本: {plaintext}")
# 加密
ciphertext_base64 = encrypt(plaintext, key, iv)
print(f"加密后的Base64编码: {ciphertext_base64}")
# 解密
decrypted_text = decrypt(ciphertext_base64, key, iv)
print(f"解密后的文本: {decrypted_text}")
RSA 非对称加密实践(python版)
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.backends import default_backend
import base64
# 生成RSA密钥对
def generate_rsa_keys():
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
return private_key, public_key
# 加密数据
def encrypt(plaintext, public_key):
ciphertext = public_key.encrypt(
plaintext.encode('utf-8'),
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return base64.b64encode(ciphertext).decode('utf-8')
# 解密数据
def decrypt(ciphertext_base64, private_key):
ciphertext = base64.b64decode(ciphertext_base64)
plaintext = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return plaintext.decode('utf-8')
# 示例使用
plaintext = "Hello, RSA!"
print(f"原始文本: {plaintext}")
# 生成RSA密钥对
private_key, public_key = generate_rsa_keys()
# 打印公钥和私钥
private_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
public_pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(f"私钥 (PEM):\n{private_pem.decode('utf-8')}")
print(f"公钥 (PEM):\n{public_pem.decode('utf-8')}")
# 加密
ciphertext_base64 = encrypt(plaintext, public_key)
print(f"加密后的Base64编码: {ciphertext_base64}")
# 解密
decrypted_text = decrypt(ciphertext_base64, private_key)
print(f"解密后的文本: {decrypted_text}")