【常见加密方法汇总】Python对三要素进行加密实现

平常我们经常需要对数据进行传输,而有些敏感信息的传输需要进行加密处理,防止数据泄露。

比如姓名、手机号、身份证号(简称三要素)等的传输。

现在我们要对三方数据进行测试,需提供三要素给对方,对方反馈相应标签给我们。

此时需要对三要素进行加密,且不同的三方机构对加密方式有不同要求,需按机构的要求进行数据提供。

本文梳理出三方数据测试常见的加密方式,不管机构需要哪一种,都可以快速地实现。

一、Python中常见加密方式

Python中常见的加密方式有以下几种:

  1. 哈希加密:如MD5、SHA1、SHA256等。这种加密方式将原始数据(通常是字符串)转换为固定长度的散列值。这是一种单向过程,即一旦数据被哈希,它不能被“解密”回原始数据。

  2. 对称加密:如AES、DES等。这种加密方式使用相同的密钥进行加密和解密。

  3. 非对称加密:如RSA、DSA等。这种加密方式使用一对密钥,一个用于加密,另一个用于解密。通常,一个是公钥,可以公开分享,另一个是私钥,需要保密。

  4. Base64编码:严格来说,Base64并不是一种加密算法,它更多是一种编码方式。但是,由于它可以将信息转换为看起来像是随机字符的字符串,所以有时被用于简单的“加密”。

本文介绍三方数据测试常用的MD5、SHA256、AES加密。

二、安装包

AES加密需安装pycryptodome包。打开cmd,安装语句如下:

pip install pycryptodome  -i https://pypi.tuna.tsinghua.edu.cn/simple

若安装成功会显示如下:

三、不同加密方式实现

1 生成三要素数据

首先生成三要素数据(纯虚构)进行测试,具体代码如下:

import pandas as pd

date = pd.DataFrame([['杨幂', '43052219980512', '13166456975'], ['杨紫', '43052219940413', '13166456976'], ['刘诗雯', '43052220010318', '13166456977']], columns=['姓名', '身份证号', '手机号'])
date

得到结果:


2 对三要素进行MD5加密

接着对三要素进行MD5加密,代码如下:

import hashlib as hb

method = 'md5'
column_list = ['姓名', '身份证号', '手机号']
df = date.copy()
for i in column_list:
    if method == 'md5':
        df[i + '_MD5'] = df[i].map(lambda x: hb.md5(str(x).encode('utf-8')).hexdigest())
    if method == 'sha256':
        df[i + '_SHA256'] = df[i].map(lambda x:hb.sha256(str(x).encode('utf-8')).hexdigest())
df

其中,method中填入想加密的方式,选md5。

column_list中填入数据框中想用method方法加密的列。

得到结果:

在这里插入图片描述

从结果知数据框中新增了对应加密的列。

3 对三要素进行SHA256加密


接着对三要素进行SHA256加密,代码如下:

```bash
import hashlib as hb

method = 'sha256'
column_list = ['姓名', '身份证号', '手机号']
df = date.copy()
for i in column_list:
    if method == 'md5':
        df[i + '_MD5'] = df[i].map(lambda x: hb.md5(str(x).encode('utf-8')).hexdigest())
    if method == 'sha256':
        df[i + '_SHA256'] = df[i].map(lambda x:hb.sha256(str(x).encode('utf-8')).hexdigest())
df

其中method中填入想加密的方式,选sha256。

column_list中填入数据框中想用method方法加密的列。

得到结果:

从结果知数据框中新增了对应加密的列,且数据长度比MD5加密要长。

经数据统计发现MD5加密后长度为32,SHA256加密后长度为64。

4 对三要素进行AES加密

AES加密最常用的模式就是ECB模式和CBC模式,俩者区别就是ECB不需要iv偏移量,而CBC需要。

1.ECB模式加密,代码如下:

from Crypto.Cipher import AES

password = b'1234567812345678' 
text = b'abcdefghijklmnop'
aes = AES.new(password, AES.MODE_ECB) 
en_text = aes.encrypt(text) 
print("密文:",en_text) 
den_text = aes.decrypt(en_text) 
print("明文:",den_text)

password:密钥,b表示转换密码为bytes类型。

text:需加密的内容。

aes:创建一个aes对象,指定加密模式为ECB。

aes.encrypt:对text进行加密。

aes.decrypt:对加密内容进行解密。

得到结果:

密文:b"^\x14\xf4nfb)\x10\xbf\xe9\xa9\xec'r\x85&"
明文:b'abcdefghijklmnop'

这里有两个需要注意的点,大家可以自行测试。

注1: 密钥必须为16字节或16字节倍数的字节型数据。

注2: 明文必须为16字节或者16字节倍数的字节型数据,如果不够16字节需要进行补全。

2.CBC模式加密,代码如下:

from Crypto.Cipher import AES

password = b'1234567812345678' 
iv = b'1234567812345678' 
text = b'abcdefghijklmnop' 
aes = AES.new(password, AES.MODE_CBC, iv) 
en_text = aes.encrypt(text) 
print("密文:",en_text) 
aes = AES.new(password,AES.MODE_CBC, iv) 
den_text = aes.decrypt(en_text)
print("明文:",den_text)

password:密钥,b表示转换密码为bytes类型。

iv:偏移量。

text:需加密的内容。

aes.encrypt:对text进行加密。

aes.decrypt:对加密内容进行解密。

得到结果:

密文:b't\xe6\xbfy\xef\xd7\x83\x11G\x95\x9d_\xcd\xab\xc7\xf8'
明文:b'abcdefghijklmnop'

3.对三要素进行aes加密

首先定义加密函数,代码如下:

from Crypto.Cipher import AES
import base64
import binascii

# 数据类
class MData():
    def __init__(self, data = b"",characterSet='utf-8'):
        # data肯定为bytes
        self.data = data
        self.characterSet = characterSet
  
    def saveData(self,FileName):
        with open(FileName,'wb') as f:
            f.write(self.data)

    def fromString(self,data):
        self.data = data.encode(self.characterSet)
        return self.data

    def fromBase64(self,data):
        self.data = base64.b64decode(data.encode(self.characterSet))
        return self.data

    def fromHexStr(self,data):
        self.data = binascii.a2b_hex(data)
        return self.data

    def toString(self):
        return self.data.decode(self.characterSet)

    def toBase64(self):
        return base64.b64encode(self.data).decode()

    def toHexStr(self):
        return binascii.b2a_hex(self.data).decode()

    def toBytes(self):
        return self.data

    def __str__(self):
        try:
            return self.toString()
        except Exception:
            return self.toBase64()


### 封装类
class AEScryptor():
    def __init__(self,key,mode,iv = '',paddingMode= "NoPadding",characterSet ="utf-8"):
        '''
        构建一个AES对象
        key: 秘钥,字节型数据
        mode: 使用模式,只提供两种,AES.MODE_CBC, AES.MODE_ECB
        iv:iv偏移量,字节型数据
        paddingMode: 填充模式,默认为NoPadding, 可选NoPadding,ZeroPadding,PKCS5Padding,PKCS7Padding
        characterSet: 字符集编码
        '''
        self.key = key
        self.mode = mode
        self.iv = iv
        self.characterSet = characterSet
        self.paddingMode = paddingMode
        self.data = ""

    def __ZeroPadding(self,data):
        data += b'\x00'
        while len(data) % 16 != 0:
            data += b'\x00'
        return data

    def __StripZeroPadding(self,data):
        data = data[:-1]
        while len(data) % 16 != 0:
            data = data.rstrip(b'\x00')
            if data[-1] != b"\x00":
                break
        return data

    def __PKCS5_7Padding(self,data):
        needSize = 16-len(data) % 16
        if needSize == 0:
            needSize = 16
        return data + needSize.to_bytes(1,'little')*needSize

    def __StripPKCS5_7Padding(self,data):
        paddingSize = data[-1]
        return data.rstrip(paddingSize.to_bytes(1,'little'))

    def __paddingData(self,data):
        if self.paddingMode == "NoPadding":
            if len(data) % 16 == 0:
                return data
            else:
                return self.__ZeroPadding(data)
        elif self.paddingMode == "ZeroPadding":
            return self.__ZeroPadding(data)
        elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
            return self.__PKCS5_7Padding(data)
        else:
            print("不支持Padding")

    def __stripPaddingData(self,data):
        if self.paddingMode == "NoPadding":
            return self.__StripZeroPadding(data)
        elif self.paddingMode == "ZeroPadding":
            return self.__StripZeroPadding(data)

        elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
            return self.__StripPKCS5_7Padding(data)
        else:
            print("不支持Padding")

    def setCharacterSet(self,characterSet):
        '''
        设置字符集编码
        characterSet: 字符集编码
        '''
        self.characterSet = characterSet

    def setPaddingMode(self,mode):
        '''
        设置填充模式
        mode: 可选NoPadding,ZeroPadding,PKCS5Padding,PKCS7Padding
        '''
        self.paddingMode = mode

    def decryptFromBase64(self,entext):
        '''
        从base64编码字符串编码进行AES解密
        entext: 数据类型str
        '''
        mData = MData(characterSet=self.characterSet)
        self.data = mData.fromBase64(entext)
        return self.__decrypt()

    def decryptFromHexStr(self,entext):
        '''
        从hexstr编码字符串编码进行AES解密
        entext: 数据类型str
        '''
        mData = MData(characterSet=self.characterSet)
        self.data = mData.fromHexStr(entext)
        return self.__decrypt()

    def decryptFromString(self,entext):
        '''
        从字符串进行AES解密
        entext: 数据类型str
        '''
        mData = MData(characterSet=self.characterSet)
        self.data = mData.fromString(entext)
        return self.__decrypt()

    def decryptFromBytes(self,entext):
        '''
        从二进制进行AES解密
        entext: 数据类型bytes
        '''
        self.data = entext
        return self.__decrypt()

    def encryptFromString(self,data):
        '''
        对字符串进行AES加密
        data: 待加密字符串,数据类型为str
        '''
        self.data = data.encode(self.characterSet)
        return self.__encrypt()

    def __encrypt(self):
        if self.mode == AES.MODE_CBC:
            aes = AES.new(self.key,self.mode,self.iv) 
        elif self.mode == AES.MODE_ECB:
            aes = AES.new(self.key,self.mode) 
        else:
            print("不支持这种模式")  
            return           

        data = self.__paddingData(self.data)
        enData = aes.encrypt(data)
        return MData(enData)

    def __decrypt(self):
        if self.mode == AES.MODE_CBC:
            aes = AES.new(self.key,self.mode,self.iv) 
        elif self.mode == AES.MODE_ECB:
            aes = AES.new(self.key,self.mode) 
        else:
            print("不支持这种模式")  
            return           
        data = aes.decrypt(self.data)
        mData = MData(self.__stripPaddingData(data),characterSet=self.characterSet)
        return mData

接着调用函数对三要素进行加密,代码如下:

password = b"1234567812345678"
iv = b'1111111122222222' 
aes = AEScryptor(password, AES.MODE_CBC, iv, paddingMode= "ZeroPadding", characterSet='utf-8')
df = date.copy()
def str_ase(wd):
    wd = wd
    rData = aes.encryptFromString(wd)
    return rData.toBase64()
df['姓名_ase'] = df['姓名'].apply(str_ase)
df['身份证号_ase'] = df['身份证号'].apply(str_ase)
df['手机号_ase'] = df['手机号'].apply(str_ase)
df

password:密钥,可自行更改。

iv:偏移量。

str_aes:对字符进行ase加密的函数。

得到结果:

在这里插入图片描述

可以发现和MD5、SHA256一样,都在后面增加了aes加密的列。

最后测试对aes加密的姓名进行解密,看是否和明文一致,代码如下:

rData = aes.decryptFromBase64(df['姓名_ase'][0])
print("明文:",rData)

得到结果:

明文:杨幂

可以发现结果是一致的。

感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

img
img

二、Python必备开发工具

工具都帮大家整理好了,安装就可直接上手!img

三、最新Python学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

img

四、Python视频合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

六、面试宝典

在这里插入图片描述

在这里插入图片描述

简历模板在这里插入图片描述
若有侵权,请联系删除
  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值