Python基础之数据加密(收藏这一篇就够了!)

Python基础之数据加密

备注: 本文的代码示例可以直接复制使用,只要传入对应参数即可~~ 方便实用!

1. 准备工作

重点:首先确保我们待加密的内容是Bytes格式!

我们所说的加密方式,都是对二进制编码的格式进行加密的。所以,在加密之前,我们要首先确保我们待加密的内容是Bytes格式,否则会报错。 那么我们如何得到Bytes格式呢? 秘诀就是使用encode()和decode()方法; 代码如下:

str = 'I LOVE China! 我爱你中国!'
str_en = str.encode('utf-8')  # 将内容变为 Bytes格式 ! 这样才可以加密!
print(str_en)    # b'I LOVE China! \xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\xe4\xb8\xad\xe5\x9b\xbd\xef\xbc\x81'

str_de = str_en.decode('utf-8')  # 解密后,将内容变回字符串内容,这样才可读;
print(str_de)    # I LOVE China! 我爱你中国!

加密解密步骤:

  1. 加密内容.encode(‘utf-8’),将加密内容变为Bytes格式;
  2. 进行加密;
  3. 进行解密;
  4. 解密后的内容.decode(‘utf-8’),将解密内容变得可读;

2. MD5加密

MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。

2.1 加密规则

MD5算法的原理可简要的叙述为:MD5码以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

2.2 应用场景

  • 密码管理:一般数据库中所存储的密码,都是经过MD5加密处理的,这种加密没有解密的办法,只能正向运算(加密),不能反向运算(解密)。所以当我们要求管理员查看一下我们的密码是什么的时候,管理员会告诉我们:我只能给你重置密码,原因就在于此;虽然MD5也存在漏洞,但还是相对安全的;

  • 电子签名:我们下载各类文件时,下载页面上除了会提供软件的下载地址以外,还会给出一串长长的字符串。这串字符串其实就是该软件的MD5 值,它的作用就在于下载该软件后,对下载得到的文件用专门的软件(如 Windows MD5 check 等)做一次 MD5 校验,以确保我们获得的文件与该站点提供的文件为同一文件。

2.3 代码实例

  1. 一般的MD5加密
# 1. md5加密
import hashlib
str = 'I LOVE China! 我爱你中国!'
str_en = str.encode('utf-8')

h = hashlib.md5(str_en)
h_en = h.hexdigest()
print(h_en)   # 1c07f68a93ec867b4b315b90f2098b24
  1. 带参数的MD5加密
    MD5虽然加密的安全性相对较好,但仍可以被撞库破解,为增加安全性,我们可以再传入一个参数,相当于再进行一次加密,提高安全性,方法如下:
# 增加自己的参数'admin',可以防止撞库破解密码;
str = 'I LOVE China! 我爱你中国!'
str_en = str.encode('utf-8')

h = hashlib.md5(str_en)
h.update('admin'.encode('utf-8'))
h_en = h.hexdigest()
print(h_en)
  1. 文件加密
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author:Zhang Kai time:2020/10/22
import hashlib
 
def get_file_md5(f):
    str = hashlib.md5()
    while True:
        data = f.read(10240)
        if not data:
            break
        str.update(data)
    return str.hexdigest()

with open(File_Name, 'rb') as f:
    file_md5 = get_file_md5(f)     # 得到文件对应的加密值,下载结束后,对比此值,即可以判断是否为同一文件;

2.4 sha1 加密

SHA-1(英语:Secure Hash Algorithm 1,中文名:安全散列算法1)是一种密码散列函数,美国国家安全局设计,基于MD5,但比MD5更安全,使用方法与MD5完全一致,如下:

import hashlib
str = 'I LOVE China! 我爱你中国!'
str_en = str.encode('utf-8')

h = hashlib.sha1(str_en)
h.update('admin'.encode('utf-8'))
h_en = h.hexdigest()
print(h_en)  # ab4d75034500b6f6a8a152df7a1f67349ead6606,比MD5多8位;

3. Base64加密

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。由于以上优点,Base64被广泛应用于计算机的各个领域。

3.1 加密规则

  1. 把3个字节变成4个字节。
  2. 每76个字符加一个换行符。
  3. 最后的结束符也要处理。

3.2 应用场景

  • 迅雷下载的专用地址链接是使用Base64’加密’的;
  • QQ旋风也是使用Base64’加密’的;

备注:这里的加密都打上了引号,因为与其说是加密,不如说是按照规则,对数据进行编码,把原本有意义的内容,编码成必须解码才能阅读的内容;

3.3 代码实例

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author:Zhang Kai time:2020/10/22
# 2. BASE64
import base64
str = 'I LOVE China! 我爱你中国!'
str_en = str.encode('utf-8')

b64_en= base64.b64encode(str_en)
print(b64_en)   # b'SSBMT1ZFIENoaW5hISDmiJHniLHkvaDkuK3lm73vvIE='

b64_de = base64.b64decode(b64_en)
print(b64_de)    # b'I LOVE China! \xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\xe4\xb8\xad\xe5\x9b\xbd\xef\xbc\x81'
str_de = b64_de.decode('utf-8')
print(str_de)    # I LOVE China! 我爱你中国!

4. AES

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

4.1 加密规则

AES加密数据块和密钥长度可以是128b、192b、256b中的任意一个。AES加密有很多轮的重复和变换。大致步骤如下:①密钥扩展(Key Expansion);②初始轮(InitialRound);③重复轮(Rounds),每一重复轮又包括字节间减法运算(SubBytes)、行移位(ShiftRows)、列混合(MixColurmns)、轮密钥加法运算(AddRoundKey)等操作;①最终轮(Final Round),最终轮没有列混合操作(MixColumns)。

4.2 应用场景

AES算法 用于传递不适合明文传输的报文。

4.3 代码实例

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author:Zhang Kai time:2020/10/22

import base64
from Crypto.Cipher import AES

'''
采用AES对称加密算法
'''
# str不是16的倍数那就补足为16的倍数
def add_to_16(message):
    while len(message) % 16 != 0:
        message = str(message)
        message += '\0'
        # message = str(message)
    return message  # 返回bytes


# 加密方法
def encrypt_oracle(message,key_pri):
    '''
    加密函数,传入明文 & 秘钥,返回密文;
    :param message: 明文
    :param key_pri: 秘钥
    :return:encrypted  密文
    '''
    # 初始化加密器
    aes = AES.new(add_to_16(key_pri), AES.MODE_ECB)
    # 将明文转为 bytes
    message_bytes = message.encode('utf-8')
    # 长度调整
    message_16 = add_to_16(message_bytes)
    #先进行aes加密
    encrypt_aes = aes.encrypt(message_16)
    #用base64转成字符串形式
    encrypt_aes_64 = base64.b64encode(encrypt_aes)
    return encrypt_aes_64


# 解密方法
def decrypt_oralce(message,key_pri):
    '''
    解密函数,传入密文 & 秘钥,返回明文;
    :param message: 密文
    :param key_pri: 秘钥
    :return: encrypted 明文
    '''
    # 初始化加密器
    aes = AES.new(add_to_16(key_pri), AES.MODE_ECB)
    #优先逆向解密base64成bytes
    message_de64 = base64.b64decode(message)
    # 解密 aes
    message_de64_deaes = aes.decrypt(message_de64)
    message_de64_deaes_de = message_de64_deaes.decode('utf-8')
    return message_de64_deaes_de


message = 'Tommorrow is another day!over!'     # 待加密内容
key_pri = '123456'                              # 密码

content_en = encrypt_oracle(message,key_pri)    # 加密
print('加密后,密文为:',content_en)            # 加密后,密文为: b'LbzC28Y/ZIgvQ1SszLrlciocu1D8HNDTcLUaUXvCgvo='

content = decrypt_oralce(content_en,key_pri)    # 解密
print('解密后,明文为:',content)               # 解密后,明文为: Tommorrow is another day!over!

5. RSA

RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的 。

RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,"由已知加密密钥推导出解密密钥在计算上是不可行的"密码体制。RSA允许你选择公钥的大小。512位的密钥被视为不安全的;768位的密钥不用担心受到除了国家安全管理(NSA)外的其他事物的危害;1024位的密钥几乎是安全的。

5.1 加密原理

RSA公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

5.2 代码实例

# RSA
import rsa

def rsaEncrypt(message):
    '''
    RSA加密函数
    传入需要加密的内容,进行RSA加密,并返回密文 & 私钥 & 公钥
    :param message: 需要加密的内容,明文
    :return: 密文 & 私钥 & 公钥
    '''
    key_pub,key_pri = rsa.newkeys(1024)
    # print(key_pri)
    # print(key_pub)
    content = message.encode('utf-8')
    crypto = rsa.encrypt(content,key_pub)
    return (crypto,key_pri,key_pub)


def rsaDecrypt(message,key_pri):
    '''
    RSA 解密函数,传入密文 & 私钥,得到明文;
    :param message: 密文
    :param key_pri: 私钥
    :return: 明文
    '''
    content = rsa.decrypt(message,key_pri)
    return content.decode('utf-8')

# 公钥加密,私钥解密

message='I Love China. 我爱你中国!'

print('加密前:',message)  # 加密前: I Love China. 我爱你中国!

crypto,key_pri,key_pub = rsaEncrypt(message)

print('加密后:',crypto)    # 加密后: b';\x1fT\x0b\xa2\xc2t\x18\xf2z\x85p\t>\xdc@%\xd4\xf3>i1\xae\xe9=\x993>\xed!\xc9?F\xcb\xde\xe1\xa5\xf0\xe9\xde\xc3\x16\xf4W\x19;\x83B\x1c\xa7\xc8k\xc9EB\xdd\x94\xad7\xda\x7f{\xec\x9f\x99\xbfd\x87\xf0d\xbc\xfe\xef_\xd9;\x18s{l\xcb\xd5u\xb7/\xf4FX\xda\xd4\xa1\xe6\xce|\xe0[<\xe4\xe2j\xb9N\xc4\x93\x17\xe7J\xeey\xbd\x1a\xd8.\x0b)\xcb\x98\xc4\x96\xb9b\t\xdc\x18]2\xdfy'
print('秘钥为:',key_pri)   # 秘钥为: PrivateKey(115288028345818733754881460912555806638911383959807908842585241310442843853213667112358247839422013848032677508051802527090846065467533765017680180661692630683981532520607475409309404078951405099846021972426884336220213989970308538119345752815652299922371343220268410359092002773721528507791837782603361434249, 65537, 72671372491785063554143583498765474892962268379138876088256082881055042532006497124961953957220544334895981514795123582047544773342223284047871955302686464986848482351432416996957016628407054177594256525025069157980131024957403886435812321512561610952210861350247053560059407031244790602637847816964556926465, 38939822841624334244626968212850549717962185656658548767156085704609096413636024697954233697763690441579951219223510491427663677756196233739375481382535403537584193, 2960671619249966096061431500671042485145295502851556909042124706260452571275538786999969819708964185223862037824834932783401994640273454183045193)
print('公钥为:',key_pub)   # 公钥为: PublicKey(115288028345818733754881460912555806638911383959807908842585241310442843853213667112358247839422013848032677508051802527090846065467533765017680180661692630683981532520607475409309404078951405099846021972426884336220213989970308538119345752815652299922371343220268410359092002773721528507791837782603361434249, 65537)

content = rsaDecrypt(crypto,key_pri)
print('明文为:',content)   # 明文为: I Love China. 我爱你中国!

猜你喜欢

转载自blog.csdn.net/weixin_47139649/article/details/109221698