您现在的位置是:网站首页 > 博客日记 >

常见的加密算法

作者:YXN-python 阅读量:23 发布日期:2024-10-25

URL encode加密

当URL中出现中文时,或者传递的参数含中文时,浏览器可以正常的显示中文,但是当你把它复制下来的时候便会发现是一串含有百分号的字符,这其实是正常的。

import urllib.parse

text = '我爱学习'
s = urllib.parse.quote(text)
print(s)
u = urllib.parse.unquote(s)
print(u)

上面的代码,使用urllib.parse.unquote()方法便可以将编码重新转换为中文

运行结果

%E6%88%91%E7%88%B1%E5%AD%A6%E4%B9%A0
我爱学习

unicode编码

这种其实不算加密与解密的过程,应该属于编码与解码,这种也是针对中文字符

text = '你好'
# 编码
entext = text.encode('unicode-escape').decode()
print(entext)

# 解码
detext = entext.encode().decode('unicode-escape')
print(detext)

在进行解码时,先通过entext.encode()方法将编码好的数据转换为二进制,再通过decode()方法将二进制转换为字符串。

运行结果

\u4f60\u597d
你好

Base64加密

base64是一种用64个字符来表示任意二进制数据的方法

import base64


# 加密
def base64_encode(data):
    encode_data = base64.b64encode(data.encode())
    return encode_data.decode()


# 解密
def base64_decode(encode_data):
    decode_data = base64.b64decode(encode_data)
    return decode_data.decode()


if __name__ == '__main__':
    text = 'I love Python'
    encode_data = base64_encode(text)
    print(encode_data)
    decode_data = base64_decode(encode_data.encode())
    print(decode_data)

运行结果

SSBsb3ZlIFB5dGhvbg==
I love Python

MD5

MD5的全称是消息摘要算法。消息摘要算法的加密是单向的,意味着加密之后就无法解密,当然目前很多网站不停的运算MD5算法的解密,就是将加密与解密数据形成一个映射。

另外,消息摘要算法的特征是提取明文的重要特征进行加密,也就是说两个不同的明文可能出现的密文是一样的,不过概率极低。

另一个特征则是,其密文的长度是固定的,它通过一个函数,把任意长度的数据转换为长度固定的数据串(通常用十六进制的字符表示)

import hashlib


def md5_test1():
    text = 'I love Python'
    md5 = hashlib.new('md5', text.encode('utf-8'))
    print(md5.hexdigest())
    print(len(md5.hexdigest()))


def md5_test2():
    md5 = hashlib.md5()
    md5.update('I love '.encode('utf-8'))
    md5.update('Python'.encode('utf-8'))
    print(md5.hexdigest())


if __name__ == '__main__':
    md5_test1()
    md5_test2()

上述代码,以两种不同的方式对字符串进行了加密的过程,一种是通过直接将一串字符进行加密,另一种情况是将字符进行拼接加密。

运行结果如下:

27eb2f69c24aa5f3503a6ae610f23a83
32
27eb2f69c24aa5f3503a6ae610f23a83

PBKDF2

PBKDF2是RSA实验室的公钥加密标准(PKCS)系列的一部分。

它是将明文和盐值(salt)作为输入参数,然后进行重复运算,并最终产生密钥,如果重复的次数足够大,破解的成本就会比较高。同样,它也是用十六进制数表示。

注意:

pycrypto、pycryptodome、crypto是同一个东西,crypto在python中的名字是pycrypto,它是一个第三方库,但是已经停更了三年,所以不建议安装这个库。

解决方法是:pip install pycryptodome

但是导入模块是有问题的,这个时候只要修改一个文件夹的名称即可。

在python的安装文件夹下的\Lib\site-packages,下面有个文件夹叫做crypto,将小写的c改为大写的C即可。

import binascii
from Crypto.Hash import SHA1
from Crypto.Protocol.KDF import PBKDF2


text = 'I love Python'
salt = b'123456'
result = PBKDF2(text, salt, count=1000, hmac_hash_module=SHA1)
print(binascii.hexlify(result).decode())
print(len(binascii.hexlify(result).decode()))

运行结果

757cf385b9857d7a27d4edc0cf557d6c
32

SHA

全称是安全哈希算法,主要使用于安全签名标准里面定义的数字签名算法。SHA通常指的是其家族的五个算法:SHA-1、SHA-224、SHA-256、SHA-384、SHA-512,后四者有时并称为SHA-2、SHA是比MD5更安全的摘要算法。MD5密文是32位、而SHA-1是40位,版本越强、密文越长,代价是速度越慢。

import hashlib


def sha1_test1():
    text = 'I love Python'
    sha1 = hashlib.new('sha1', text.encode('utf-8'))
    print(sha1.hexdigest())


def sha2_test2():
    sha1 = hashlib.sha1()
    text = 'I love Python'
    sha1.update(text.encode('utf-8'))
    print(sha1.hexdigest())


if __name__ == '__main__':
    sha1_test1()
    sha2_test2()

运行结果

9233eac58259dd3a13d6c9c59f8001823b6b1fee
9233eac58259dd3a13d6c9c59f8001823b6b1fee

HMAC

简介:全称散列消息认证码、密钥相关的哈希运算消息认证码。

HMAC加密算法是一种安全的基于加密的Hash函数和共享密钥的消息认证协议,它要求通信双方共享密钥Key、约定算法、对报文进行Hash运算,形成固定长度的认证码。

import hashlib
import hmac


def hmac_test1():
    massage = b'I love Python'
    key = b'secret'
    md5 = hmac.new(key, massage, digestmod='md5')
    print(md5.hexdigest())


def hmac_test2():
    key = 'secret'.encode('utf-8')
    sha1 = hmac.new(key, digestmod='md5')
    sha1.update('I love '.encode('utf-8'))
    sha1.update('Python'.encode('utf-8'))
    print(sha1.hexdigest())


if __name__ == '__main__':
    hmac_test1()
    hmac_test2()

运行结果

49c5cc68061a01a30a71f52cb70201e5
49c5cc68061a01a30a71f52cb70201e5

AES

全称是高级加密标准,加密时主要参数是密文、密钥和偏移量。它是一种对称加密算法。

mode 支持:CBC,CFB,CTR,CTRGladman,ECB,OFB 等。

padding 支持:ZeroPadding,NoPadding,AnsiX923,Iso10126,Iso97971,Pkcs7 等

import base64
from Crypto.Cipher import AES


# 需要补位,str不是16的倍数那就补足为16的倍数
def add_to_16(value):
    while len(value) % 16 != 0:
        value += '\0'
    return str.encode(value)


# 加密方法
def aes_encrypt(key, t, iv):
    aes = AES.new(add_to_16(key), AES.MODE_CBC, add_to_16(iv))  # 初始化加密器
    encrypt_aes = aes.encrypt(add_to_16(t))  # 先进行 aes 加密
    # 执行加密并转码返回 bytes
    encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8')
    return encrypted_text


# 解密方法
def aes_decrypt(key, t, iv):
    # 初始化加密器
    aes = AES.new(add_to_16(key), AES.MODE_CBC, add_to_16(iv))
    # 优先逆向解密 base64 成 bytes
    base64_decrypted = base64.decodebytes(t.encode(encoding='utf-8'))
    # 执行解密密并转码返回str
    decrypted_text = str(aes.decrypt(base64_decrypted), encoding='utf-8').replace('\0', '')
    return decrypted_text


if __name__ == '__main__':
    secret_key = '12345678'  # 密钥
    text = 'I love Python!'  # 加密对象
    iv = secret_key  # 初始向量
    encrypted_str = aes_encrypt(secret_key, text, iv)
    print('加密字符串:', encrypted_str)
    decrypted_str = aes_decrypt(secret_key, encrypted_str, iv)
    print('解密字符串:', decrypted_str)

# 加密字符串:lAVKvkQh+GtdNpoKf4/mHA==
# 解密字符串:I love Python!

运行结果

加密字符串:lAVKvkQh+GtdNpoKf4/mHA==
解密字符串:I love Python

RSA非对称加密

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

def generate_rsa_keys():
    # 生成RSA密钥对
    key = RSA.generate(2048)
    private_key = key.export_key()
    public_key = key.publickey().export_key()
    return private_key, public_key

def rsa_encrypt(public_key, message):
    # 使用公钥加密
    key = RSA.import_key(public_key)
    cipher = PKCS1_OAEP.new(key)
    return cipher.encrypt(message.encode())

def rsa_decrypt(private_key, encrypted_msg):
    # 使用私钥解密
    key = RSA.import_key(private_key)
    cipher = PKCS1_OAEP.new(key)
    return cipher.decrypt(encrypted_msg).decode()


if __name__ == "__main__":
    # 生成密钥对
    private_key, public_key = generate_rsa_keys()
    print("私钥:", private_key.decode())
    print("公钥:", public_key.decode())

    # 要加密的消息
    message = "Hello, this is a secret message!"

    # 加密消息
    encrypted_message = rsa_encrypt(public_key, message)
    print("加密:", encrypted_message)

    # 解密消息
    decrypted_message = rsa_decrypt(private_key, encrypted_message)
    print("解密:", decrypted_message)

运行结果

私钥: -----BEGIN RSA PRIVATE KEY-----
    MIIEpAIBAAKCAQEAt+ERBdNpv6aRFRnhs6Gbq610FEBXjz/kuQOvmT6pfchPMZvk
    T14lCKIMEl+6UpucvasMSfvrhtu2QXBgvAEJktJANZm+Had/4EWyUuCzMpJILjJY
    ktJgX5Cc8M0BUoSjLfAKHmtyxgDbRjpwN8FcXhaGbuCCJuYpoXRjewRM6enQEqs8
    PuGzeqM4lLsd7RfxEWVTi++L1U6LbqsxrdlnHjPTG9qPxPeCDfGYWttkUu8gz2Ks
    jOewGcTP+kRuzgaxbWVRHnzuuNFOINU7l8K31n5RJlHtgmvL5CBfeW73/GChNA6/
    Y3F4liuOqoLDGvtzmdvM3/rmU/07eKYvjzcwRwIDAQABAoIBACH2n1dNImY01O1p
    12d/fSprolovPD0IVy3ZQXDzwwipm/8UxUnnoL2EeOhX6Clj9sKNunpb3rgNEw/p
    OuTe6C7HSPbdi+EcVCFPnk1ylYbMwCpQQE32L7jXFDXiF9FvEFjm0mel/xAVjmrd
    Vmbl/zKdxHzsWP3oW14oCkvpkm9N4Tg4efRH/npU2HNzXSAEYBRTm45fZnS3aQch
    GKudoaJp57SN+3F9mh4JalH80n83ikALGM2+b8tJzuyi0TayeZWbNgl7pVNijVCx
    wDHAthwTW5jMAn7xxY3Eg9TuA/resWCdVuGLeS6sv0c4T+lmkqLHOn0+WNshWU25
    vG6z3NECgYEAyiS6V4qFO7s/m8T1W2kX9iLFzCg0f0LMB6BAwAXB/EzQzsc40M9S
    2bVM9D4wHiC5LctzwgL6q1QFmoeCHDBKRw8UjFkotNUIXcCQ7N9S7VvmrouoS5Fv
    fFG9e9Bdx+Q51eYww1j2pSmJm2Tsn6cdm8JAijB0Ba+NFzeEL9BLhFkCgYEA6N6d
    atpt4L3xtmUP6ikdeuKzv8V1My/FdGC3jgsvmwj5Zl1EVYESqHsVGZ/et72OVtgV
    5UwgH2dprjzmXNHk7f5eu+qJGdQNnSGU+CvIC6785mxmA+wdprD8hNffHFK30uk6
    egYSzaBntXordrgvuoCKt4UbW4Zhyz1eGV5ERZ8CgYEAlBIPRWy8Z6Kj13CQ4aK7
    4JpcFU4mFkpRtgxXIdGV5UBHfBBGt/4GDF9XvVmIWalSvA7Z/nW8NJ/ZcvZsAkYF
    QsPzI1N0E/IwrKwP/NMhpai584Vtg91GsuQVToq1B2VQUDTL52xVT2p72A43nkMF
    10CVkiQn+Lo9OZJ7C6MijhECgYEAshQTI3R4VEZNAqNUQUhB0AhvVvakQomEoROZ
    KtmpBREez8YBDLYQ06CUKS1VfwNJR2YlkFzfr8RAT8soitDEFa/RODkJsSO1aXUV
    25Z3e1/M7FT2yocUwbVU1i3S43DqPDK40jm0xWSmCmSrujTt4tyLt/3lRt+EB40d
    WZ757JcCgYBw4gwC1sjbJEMp0Af80BKZ8/TNP9VpJeSvo0nvsdMkH73P/jzXraYw
    wcgMyj4cDIFITdurd1VrojOQQGSjKdLfpwOK9GdgEXJZFJvEvyZHHv+yuO7xQSnC
    mGWAqEct4F24X+R2X2/Be9XtyptHCOTIK1zxlsmOsR6IYiNIyS4jKA==
    -----END RSA PRIVATE KEY-----
    公钥: -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt+ERBdNpv6aRFRnhs6Gb
    q610FEBXjz/kuQOvmT6pfchPMZvkT14lCKIMEl+6UpucvasMSfvrhtu2QXBgvAEJ
    ktJANZm+Had/4EWyUuCzMpJILjJYktJgX5Cc8M0BUoSjLfAKHmtyxgDbRjpwN8Fc
    XhaGbuCCJuYpoXRjewRM6enQEqs8PuGzeqM4lLsd7RfxEWVTi++L1U6Lbqsxrdln
    HjPTG9qPxPeCDfGYWttkUu8gz2KsjOewGcTP+kRuzgaxbWVRHnzuuNFOINU7l8K3
    1n5RJlHtgmvL5CBfeW73/GChNA6/Y3F4liuOqoLDGvtzmdvM3/rmU/07eKYvjzcw
    RwIDAQAB
    -----END PUBLIC KEY-----
    加密: b'mb\xf8Jx\x8e\\\x90\xe5\x81\xeb-1\x05oO\x8f_\x9a\x01\xd0]\xba\xb1\xe4\xd3\x90\x04\x04\x14\x7f\xf5\xf8\x96\x91\xc2w\xb5\x99\xf9\xca\xe7$\x94%\xac\x10\x10iO\x8c\x92Q\xf6F\x968Q\x89\xe4\x97\xf4\x99\xcc\xb3\xb3,\x8e\xa8\xb1\xa9\x84\x15uob\x16\x0ft\xe5\xccs\xa5s\xc7\xdd\xc7\xf8j\xdfX\xb1\x80\xa6?t\x83\xf5\xbf\x9fy\xc6IO\x02\xb8X&\x80/P\x1d0_6g\xac\x96\xf1\xbc\x19\xc6\xd6\xec\x83\xfd\xf0\xa9C\xc7(E\xd4\xfeq\x02\x8e.\xdd\x88\xd6\xda_\x0b\xc8\xce\xb0\xfb\xcb\x1a\xe4\x81`u,V\xb3rH\xe6\xf5\xdf\x8e\x1a^og\xc6\xc6\xb1k\xa3\xea\x14\xbas\xc6v\xef\x81\xb9\x08*\x81c\xd1\xc1\x07\xfd\x1d^\x0e\xa9\x94\xe5\xc1\x12\x1a6\x97V\x9dL\xae\x1a\x8d\x8e\x83\x8d\xa5\r\xf9\x15\xe57\x182t\xc3[\xa7\x92G\x87@\x84\xf1`;\x1c\xd6\x8a2\xbdt+\xbf;\xb0\x83^.\x95\x85\r\x87hM\x1d\xcd\x1a\xe0\x08\x1b\xa7\x8f'
    解密: Hello, this is a secret message!

数字签名

from Crypto import Random
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256

def sign_message(private_key, message):
    # 创建签名
    key = RSA.import_key(private_key)
    h = SHA256.new(message.encode())
    return pkcs1_15.new(key).sign(h)

def verify_signature(public_key, message, signature):
    # 验证签名
    key = RSA.import_key(public_key)
    h = SHA256.new(message.encode())
    try:
        pkcs1_15.new(key).verify(h, signature)
        return True
    except (ValueError, TypeError):
        return False


if __name__ == "__main__":
    # 生成密钥对
    key = RSA.generate(2048, Random.new().read)
    private_key = key.export_key()
    public_key = key.publickey().export_key()

    print(f"私钥: {private_key.decode()}")
    print(f"公钥: {public_key.decode()}")

    # 签名消息
    message = "这是一封需要签名的邮件."
    signature = sign_message(private_key, message)
    print(f"签名: {signature}")

    # 验证签名
    is_valid = verify_signature(public_key, message, signature)
    print(f"签名有效吗? {is_valid}")
    

运行结果

私钥: -----BEGIN RSA PRIVATE KEY-----
    MIIEowIBAAKCAQEAk6t8ooVpORraHKVgGAiJw4x8vJtSS2jkEyNM6IMen8sVLiAy
    w8orLLOdgQGhhSKkeMa1iTirLYh8lTT2O8c8lfArUbnVT4ku6E0Le7n8bOGxzgZ0
    22s9MlqO0rsuBQyEV3p3k9ObXnLiwP1mY2KVjkl9dHP3X5dgXpz6n/2xBhVmOzVd
    0vMbtJlJrPOxEjwdfu0a2DUB29kVWhViYbQ85JK0rdyOscLYmo3fOS56Jq7oZpql
    rg+MesecWBPvIOvKI6NCpj8syR97y9rviGx7cnrtGlEZ7LLJoce7taKd5QTK13L0
    KkJSoDHnqSfzqk3QSffsE1tNnurkbPENSvCzMQIDAQABAoIBABOohiCKmx3nhba/
    i0HXzSMzrh1bngJ89bPYhLIFVovWOL0ZuzhWTxYV2Tdl1K9JE9UiOuOIID2hCFjC
    oq8FkHqzbMjl8NA0RoLVUtyHP2PtTcLMGD1nks+Dv7StB2zTpECTBJ0w0+Oobqhb
    c4hyhM9a2DErCPj4SXN++VxYJPtWpRfbYeodivT+/vqCZJb99UNQSoXaI7BGqSIo
    co/VYDLPbHP7opYhueJVofNnsSv1FgZ7HpBG80N3cS2IggWe/UFaxRSpwWW1o2uK
    Jf/xiEWjXPvWf5fqnBhppIAdJpfWQqLKX19yjuYi/Eyefhs2KtYF0N9B5n+HTG0g
    1GsyfUsCgYEAtyvpX5LazGG27wp0YC0UZdcckHNQj6KO6ezXVzs6YTVH5hoBkTMJ
    gYjCI/hgOklIqeYFuC7DH3JpZWYBi1R+RyS+MOq1HO49+CGb3oe4ur3Ra+kYM15A
    MAJpu/DBlsO2i/V2gqrlyzsdNq82Fk132fI4PnSnFrwgYm3WoSFPxJsCgYEAzmIL
    Odhp9+VsPGWhN/FNNbfgzR13s3v9cPWf6NcqJduFzqsXnC/bPr4f7779U9fCDs3H
    LPuugKaT3QpY8VB77C3T4FnRgnBo+IvYaPRkWF92NcpY8d7a8TWuwKzBQiN3dUwW
    wkh6X/efFnv0GlDmZIxXS3dzPgSsUMa+Pb3iliMCgYBa4rjrKSzTWHCybxeLWRLT
    7UZJDk6c1mXfABthNwwii5NfQuwgJZjD4x2hR25HvXEGjBGub9V1VwmgvFprzcLS
    fhK4ptyyvCuXYOW8Js+sKN8ukfvmEQ/8QlZAYJdNvVJoY6Un9LAMhQpbxdgqfMnJ
    JHxv0OXPTA0tiZ6DWMoBnQKBgDRtI3zmRMT8Oqp9Bp83ZO2ocCqquaWWcaMoQh7b
    yZEkWrFNNQov/fnKQkKcua16uYkZLOd4Z7O2nQkhf8aNM22jlpb/OgFwnLnGjIrc
    ykDIvzaa2E1Y1zU+9c1sFQvABrB9S6q+zpdiR79mbXPh6STRobtB9LxkY4GBewIk
    IlMRAoGBAIjoJTgLt5EaHrVAseVpfKh45hlp4oEIJLWMuVt0CEmxoP7tqiokNmbn
    PzWYfTgd3F5+BfAKhqJZGDspzgpUDYSMz9AiHDpI+N575MmEb+HjG37acogNNa66
    5EbDEzsylavxzpVcMy6DD0WIn8H4Tm/kEPoQKDCm5w3hWQTog8T6
    -----END RSA PRIVATE KEY-----
    公钥: -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk6t8ooVpORraHKVgGAiJ
    w4x8vJtSS2jkEyNM6IMen8sVLiAyw8orLLOdgQGhhSKkeMa1iTirLYh8lTT2O8c8
    lfArUbnVT4ku6E0Le7n8bOGxzgZ022s9MlqO0rsuBQyEV3p3k9ObXnLiwP1mY2KV
    jkl9dHP3X5dgXpz6n/2xBhVmOzVd0vMbtJlJrPOxEjwdfu0a2DUB29kVWhViYbQ8
    5JK0rdyOscLYmo3fOS56Jq7oZpqlrg+MesecWBPvIOvKI6NCpj8syR97y9rviGx7
    cnrtGlEZ7LLJoce7taKd5QTK13L0KkJSoDHnqSfzqk3QSffsE1tNnurkbPENSvCz
    MQIDAQAB
    -----END PUBLIC KEY-----
    签名: b'T\xab\x07\x9f\t\xcdz\xedR\xa7\xf6\xc3?\xb1Q\xfc\xefua\x0fRQ\xb67\x1d\xf0\x84n7\xc7}\x01\xc9\t\xe4\xfcd\xc5zz4D\x88\x17\xc0d\xa34\xec\x88J\x05#\xc1\x83&\xd3\xdd\xb4\x18\x8f \xad"\xfd\xdfP\xc1MH7{\xcdf2A\x08Y\x85#j\x91\x90\xa3\xba\x14\x85N#(\xa8\x99=\x14\xbc\x0b\x0e\xd9\xfaG\x02\'\xfd\xd4\x91\xfb\xf4\xfbZ\x1b\xeeW!\xc3\xb6\x00\xa8\x87*\x1fs\x0b\xecd\x0f\xaf\xaa\x17y\xadb$(\xd3*P,\xdfgY\xf1\x89\x1b\xe0{\x1c\xcf\xe9\xfc\xb6*\xcb\xb9\xe9g\x80\x1f\x05!\x15\x9c\xfe\x0c\x9e\x0e\xf8\xbd\xd2\xd5D\x17{\x03R\xb0\xa74\x10\xa9\xb4\xfaF\xa7\x11\x1a\x83*\xd2\x14\x88/\xcb\x8c\xbei\x1b\xe2\x93u\x9a\xf6\xb6\x1bIU\xad\xbf?k\xed\x9e\xba\xb0\x9a\x85\xb3y9\xde\xac4\xc1n\xf9\xe9\x03~\x18zp\x99d\xd6VCA\x13\xb4\x96\x8c\xd7\x9buv\x99\xab\x11\xbf\x06\xa8\xed\x8d\xc1rS\xae'
    签名有效吗? True

YXN-python

2024-10-25