爬虫从入门到精通(10) |使用Python实现常用的加密算法

在这里插入图片描述

一、了解常见的加密方式

1.对称加密算法

对称加密算法是指加密和解密采用相同的密钥,是可逆的(即可解密)。

  • 优点: 加密速度快
  • 缺点: 密钥的传递和保存是一个问题,参与加密和解密的双方使用的密钥是一样的,这样密钥就很容易泄露。
  • 常见算法:AES(128位、192位或256位)、DES(64位)、3DES

2.非对称加密算法

非对称加密算法是指加密和解密采用不同的密钥(公钥和私钥),因此非对称加密也叫公钥加密,是可逆的(即可解密)。公钥密码体制根据其所依据的难题一般分为三类:大素数分解问题类、离散对数问题类、椭圆曲线类。

  • 优点: 加密和解密的密钥不一致,公钥是可以公开的,只需保证私钥不被泄露即可,这样就密钥的传递变的简单很多,从而降低了被破解的几率。
  • 缺点: 加密速度慢
  • 常见算法: RSA、DSA、ECC

3.线性散列算法

  • 常见算法:MD5(常见32位/16位)、SHA1(40位)、HMAC
  • MD5单向的算法不可逆。MD5加密后的数据长度要比加密数据小的多,且长度固定,且加密后的串是唯一的。

4.Base64

  • 组成:A-Z a-z 0-9 - + =
  • 严格意义讲,Base64并不能算是一种加密算法,而是一种编码格式,是网络上最常见的用于传输8bid字节代码的编码方式之一。

5.常见123456的各种加密

# 123456的md5加密32位
e10adc3949ba59abbe56e057f20f883e

# 123456的md5加密16位
49ba59abbe56e057

# 123456的base64加密
MTIzNDU2

# 123456的sha1加密(通常40位)
7c4a8d09ca3762af61e59520943dc26494f8941b

在常见的加密中,如果看到加密数据不是16位和32位的,且加密的数据中的字母最大为f,一般是非对称或者对称加密,因为他们是16进制加密

二、使用Python实现各种加密

1.Base64

简介:Base64是最简单的加密方式,无密钥,只要拿到密文,就可以直接解密,一般情况下不单独使用,可以和其他加密方式混合使用,作为一层外部包装。严格意义讲,Base64并不能算是一种加密算法,而是一种编码格式,是网络上最常见的用于传输8bid字节代码的编码方式之一。
组成:A-Z a-z 0-9 - + =

import base64


def encrypt_to_base64(str2):
    """加密"""
    byte_str = base64.b64encode(str2.encode())  # 转化为byte类型
    base64_encrypt_str = byte_str.decode()  # 将字节串转为字符串
    return base64_encrypt_str


def decrypt_to_str(base64_encrypt_str):
    """解密"""
    base64_decrypt = base64_encrypt_str.encode()  # 字符串转为字节串
    str_decrypt = base64.b64decode(base64_decrypt).decode()  # 得到加密的字符串
    return str_decrypt


if __name__ == '__main__':
    str = '123456'
    print(encrypt_to_base64(str))
    print(decrypt_to_str(encrypt_to_base64(str)))

在这里插入图片描述

2.MD5

MD5 具有很高的安全性,可以产生出一个128位(16字节)的散列值(hash value),它对应任何字符串都可以加密成一段唯一的固定长度的代码,用于确保信息传输完整一致。目前MD5加密算法是不可逆的,当然这种方式加密的密文也不需要解密,需要的时候直接发送原始密文就好。

import hashlib


def encrypt_to_md5(str_encrypt):
    """字符串加密到md5"""
    hashlib.md5(str_encrypt.encode("utf8"))
    m = hashlib.md5(str_encrypt.encode("utf8"))
    return m.hexdigest()


if __name__ == '__main__':
    print(encrypt_to_md5('123456'))

在这里插入图片描述

3.SHA系列加密

import hashlib


def encrypt_to_sha(str_encrypt, type=1):
    if type == 1:
        # sha 1
        hash = hashlib.sha1(str_encrypt.encode("utf8"))
    elif type == 256:
        # sha 256
        hash = hashlib.sha256(str_encrypt.encode("utf8"))
    elif type == 512:
        # sha 512
        hash = hashlib.sha512(str_encrypt.encode("utf8"))
    else:
        return None
    hash.update(str_encrypt.encode("utf8"))
    value = hash.hexdigest()
    return value


if __name__ == '__main__':
    str_encrypt = "123456"
    print(encrypt_to_sha(str_encrypt))

4.HMAC

HMAC加密算法是一种安全的基于加密hash函数和共享密钥的消息认证协议。实现原理是用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。

import hmac
import hashlib


def encrypt_to_hmac(key, value, type_=hashlib.md5):
    """
    key:密钥key
    value:待加密的字符串
    type_:hash函数
    return: 加密后的16进制
    """

    mac = hmac.new(key.encode(encoding="utf-8"), value.encode("utf8"), type_)
    return mac.hexdigest()


if __name__ == '__main__':
    key = 'abc'
    value = '123456'
    type = hashlib.md5
    print(encrypt_to_hmac(key, value, type))

在这里插入图片描述

5.DES

DES是对称加密算法。是一种使用密钥加密的块算法。接口参数有三个:Key、Data、Mode。
Key为工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode工作方式:加密或解密。

python先要安装三方模块pip install pyDes

import binascii
from pyDes import des, CBC, PAD_PKCS5

# 加密过程
def des_encrypt(secret_key, value):
    """
    secret_key:key
    value:加密值
    """
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    en = k.encrypt(value, padmode=PAD_PKCS5)
    return binascii.b2a_hex(en)


# 解密过程
def des_decrypt(secret_key, value):
    """
   secret_key:key
   value:加密值
   """
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    de = k.decrypt(binascii.a2b_hex(value), padmode=PAD_PKCS5)
    return de


if __name__ == '__main__':
    secret_str = des_encrypt('12345678', 'hello')
    print(secret_str)

    clear_str = des_decrypt('12345678', secret_str)
    print(clear_str)

在这里插入图片描述

6.AES

①简单介绍

AES需要知道密钥才能解密。
分组密码加密中的四种模式有ECB、CBC、CFB、OFB。其中最常见的有ECB和CBC。

1、ECB模式
对明文分组,每组明文通过加密算法和密钥位运算得到密文,之后按照顺序将计算所得的密文连在一起即可,各段数据之间互不影响。

2、CBC模式(使用最多的模式)
CBC模式需要一个初始化向量iv(和密钥长度相等的字符串),一般通过密钥生成器获取。

加密步骤如下:

  • 首先将数据分组得到D1D2…Dn
  • 第一组数据D1与初始化向量iv位运算的结果进行加密得到第一组密文C1
  • 第二组数据D2与第一组的加密结果C1位运算以后的结果进行加密,得到第二组密文C2
  • 之后的数据以此类推,得到Cn
  • 按顺序连为C1C2C3…Cn即为加密结果。

特点:

  • 1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。每个密文块依赖于所有的信息块,明文消息中一个改变会影响所有密文块
  • 2.发送方和接收方都需要知道初始化向量
  • 3.加密过程是串行的,无法被并行化(在解密时,从两个邻接的密文块中即可得到一个平文块。因此,解密过程可以被并行化。)
  • 4.解密时初始化向量必须相同

②python模块安装

crypto模块的目的是为了提供通用的加密和哈希算法。用纯JavaScript代码实现这些功能不是不可能,但速度会非常慢。Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaScript接口,这样用起来方便,运行速度也快。

直接安装Crypto会有坑,这里我们选择安装pycryptodome模块,这个模块里会包含Crypto

pip3 install pycryptodome
pip3 install crypto

导包

from Crypto.Cipher import AES

如果出现报错:不存在Crypto,那么需要进入python包目录修改crypto为大写即可

在这里插入图片描述

③ECB加密

import base64
from Crypto.Cipher import AES


# 需要补位,补足为16的倍数,使用补0方法
def add_to_16(s):
    while len(s) % 16 != 0:
        s += '\0'
    return str.encode(s)  # 返回bytes


def encrypt(key, text):
    aes = AES.new(add_to_16(key), AES.MODE_ECB)  # 初始化加密器
    encrypted_text = str(base64.encodebytes(aes.encrypt(add_to_16(text))), encoding='utf8').replace('\n', '')  # 加密
    return encrypted_text


def decrypt(key, encrypted_text):
    aes = AES.new(add_to_16(key), AES.MODE_ECB)  # 初始化加密器
    decrypted_text = str(
        aes.decrypt(base64.decodebytes(bytes(encrypted_text, encoding='utf8'))).rstrip(b'\0').decode("utf8"))
    return decrypted_text


if __name__ == '__main__':
    key = 'abc4567890abc458'  # 密钥长度必须为16、24或32位,分别对应AES-128、AES-192和AES-256
    text = 'hello'  # 待加密文本
    encrypted_text = encrypt(key, text)
    decrypted_text = decrypt(key, encrypted_text)
    print(encrypted_text)
    print(decrypted_text)

在这里插入图片描述

④CBC加密

import base64
from Crypto.Cipher import AES

# 密钥和IV
AES_SECRET_KEY = 'abcabcabcabcabc1'  # 此处16|24|32个字符,分别对应AES-128、AES-192和AES-256
IV = 'helloBrook2abcde'  # 和密钥等长

# padding算法
BS = len(AES_SECRET_KEY)
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s: s[0:-ord(s[-1:])]


class AES_ENCRYPT:
    def __init__(self):
        self.key = AES_SECRET_KEY
        self.mode = AES.MODE_CBC

    # 加密函数
    def encrypt(self, text):
        cryptor = AES.new(self.key.encode("utf8"), self.mode, IV.encode("utf8"))
        self.ciphertext = cryptor.encrypt(bytes(pad(text), encoding="utf8"))
        # AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题,使用base64编码
        return base64.b64encode(self.ciphertext).decode("utf-8")

    # 解密函数
    def decrypt(self, text):
        decode = base64.b64decode(text)
        cryptor = AES.new(self.key.encode("utf8"), self.mode, IV.encode("utf8"))
        plain_text = cryptor.decrypt(decode)
        return unpad(plain_text).decode("utf-8")


def chinese_to_ascii(text):
    text2 = base64.b64encode(text.encode('utf-8')).decode('ascii')
    return text2


if __name__ == '__main__':
    aes_encrypt = AES_ENCRYPT()
    text = "hello123"
    e = aes_encrypt.encrypt(text)
    d = aes_encrypt.decrypt(e)
    print(text)
    print(e)
    print(d)

在这里插入图片描述
如果加密的文本有中文,先转换为ASCII,再加密

def chinese_to_ascii(text):
    text2 = base64.b64encode(text.encode('utf-8')).decode('ascii')
    return text2

7.RSA加密

这里使用rsa的公钥加密的方式

import base64
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.PublicKey import RSA


# RSA_加密
def rsajm(text, public_key):
    '''
    :param text: 原文本
    :param public_key:公钥
    :return: 加密值
    '''
    rsakey = RSA.importKey(public_key.encode())
    ciper = Cipher_pkcs1_v1_5.new(rsakey)
    en_data = base64.b64encode(ciper.encrypt(text.encode())).decode()
    return en_data


if __name__ == '__main__':
    # 公钥要传入换行
    public_key = '''-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDnOWe/gs033L/2/xR3oi6SLAMPBY5VledUqqH6dbCNOdrGX4xW+1x6NUfvmwpHRBA2C7xWDDvOIldTl0rMtERTDy9homrVqEcW6/TY+dSVFL3e2Yg2sVaehHv7FhmATkgfC2FcXt8Wvm99QpKRSrGKpcFYJwOj2F8hJh+rTG0IPQIDAQAB
    -----END PUBLIC KEY-----'''

    print rsajm('rig8yjnf029kr57igu0p2e97ys6f3y40', public_key)

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张烫麻辣亮。

谢谢老板支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值