不用说火爆一时,全网热议的Web3.0区块链技术,也不必说诸如微信支付、支付宝支付等人们几乎每天都要使用的线上支付业务,单是一个简简单单的注册/登录功能,也和加密技术脱不了干系,本次我们耙梳各种经典的加密算法,试图描摹加密算法在开发场景中的运用技巧。
可逆加密算法(对称加密)
加密算法是一种将原始数据转换为加密数据的方法。根据加密算法的不同特征,可以将其分为可逆加密算法和不可逆加密算法。
可逆加密算法也称为对称加密算法,其加密和解密过程使用相同的密钥。在这种算法中,加密数据可以通过解密算法还原为原始数据。这种算法通常用于保护数据的机密性,例如保护存储在计算机硬盘上的文件或网络传输的数据。
说白了,就是在数据的传输过程中加密,真正在业务中使用的时候,还是用明文。
比如,使用AES加密算法对文件进行加密:
from Crypto.Cipher import AES
import os
# 生成一个16字节的密钥
key = os.urandom(16)
# 初始化加密算法
cipher = AES.new(key, AES.MODE_EAX)
# 读取要加密的文件
with open('plaintext.txt', 'rb') as f:
plaintext = f.read()
# 对文件进行加密
ciphertext, tag = cipher.encrypt_and_digest(plaintext)
# 将加密后的文件保存到磁盘上
with open('ciphertext.txt', 'wb') as f:
f.write(cipher.nonce)
f.write(tag)
f.write(ciphertext)
或者使用DES算法:
from Crypto.Cipher import DES
# 生成一个8字节的密钥
key = b'secretke'
# 初始化加密算法
cipher = DES.new(key, DES.MODE_ECB)
# 要加密的字符串
plaintext = b'Hello, World!'
# 对字符串进行加密
ciphertext = cipher.encrypt(plaintext)
# 将加密后的字符串转换为十六进制格式并输出
print(ciphertext.hex())
在网络传输领域,对称加密一般都是在JWT的Token令牌加密环节使用:
class MyJwt:
def __init__(self):
# 密钥
self.secret = "1234"
# 加密方法(加入生命周期)
def encode_time(self,userinfo,lifetime=300):
# 单独声明载荷playload
playload = {
'exp':(datetime.datetime.now()+datetime.timedelta(seconds=lifetime)).timestamp(),
'data':userinfo
}
res = jwt.encode(playload,self.secret,algorithm='HS256')
return res
# 加密方法
async def encode(self,userinfo):
res = jwt.encode(userinfo,self.secret,algorithm='HS256')
return res
# 解密算法
async def decode(self,jwt_str):
res = jwt.decode(jwt_str,self.secret,algorithms=['HS256'])
return res
在实际应用中,需要选择适合具体场景的加密算法和密钥长度,并采取适当的安全措施来保护密钥,因为对于可逆加密算法来说,秘钥一旦泄露,带来的后果将会是灾难性的。
不可逆加密算法(哈希)
不可逆加密(也称哈希算法)通常用于对密码或者数据进行加密或验证,保证密码或数据的安全性。相比对称加密或非对称加密,哈希算法不需要密钥进行加密或解密,因此更加方便和高效,但它不支持解密,一旦加密后的结果生成,就无法恢复原始数据,不可逆加密算法的最常见应用场景就是把用户的明文密码加密成为密文。
比如使用SHA-256哈希算法对数据进行加密:
import hashlib
# 加密数据
message = b'hello world'
hash_object = hashlib.sha256(message)
encrypted_data = hash_object.hexdigest()
print(encrypted_data)
或者使用bcrypt算法对密码进行加密:
import bcrypt
# 加密密码
password = b'mysecretpassword'
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password, salt)
# 验证密码
password_to_check = b'mysecretpassword'
if bcrypt.checkpw(password_to_check, hashed_password):
print("Password is valid!")
else:
print("Invalid password.")
又或是使用scrypt算法对密码进行加密:
import scrypt
# 加密密码
password = b'mysecretpassword'
salt = b'saltsaltsalt'
encrypted_password = scrypt.hash(password, salt, N=16384, r=8, p=1)
# 验证密码
password_to_check = b'mysecretpassword'
if scrypt.hash(password_to_check, salt, N=16384, r=8, p=1) == encrypted_password:
print("Password is valid!")
else:
print("Invalid password.")
原理上大同小异,都是基于散列(hash)算法将原始数据映射到一个固定长度的密文上,由于不可逆加密(哈希算法)是一种单向的加密方式,无法通过解密来恢复原始数据,因此暴力破解哈希算法通常是通过对大量的可能性进行穷举来尝试匹配原始数据:
import hashlib
# 加载包含密码列表的文件
with open('passwords.txt', 'r') as f:
passwords = f.read().splitlines()
# 加载哈希值
hash_value = '5d41402abc4b2a76b9719d911017c592'
# 尝试匹配密码
for password in passwords:
if hashlib.md5(password.encode()).hexdigest() == hash_value:
print(f"Password found: {password}")
break
else:
pr