加密算法(python实现)

加密算法

一,对称加密

1.0,简介

对称加密是指 数据加密解密 使用相同的密钥。,数据的加密

  • 主要功能:通常用于保证数据的机密性。

  • 常用的加密算法:

    • DES: Data Encryption Standard,秘钥长度为56位,2003年左右被破解--秘钥可以暴力破解。
    • 3DES: DES的改进版本。
    • AES: Advanced Encryption Standard,支持的秘钥长度包括 128bits,192bits,258bits,384bits,512bits。

    ※ :密钥越长,加密和解密的时间越长

1.1,DES

特点:密钥很短,很容易被破解

简介:

DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准。

DES是一个分组加密算法,典型的DES以64位为分组对数据加密,加密和解密用的是同一个算法。

DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据**

密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1),对64位二进制数据块进行加密,分组后的明文组和56位的密钥按位替代或交换的方法形成密文组。每次加密对64位的输入数据进行16轮编码,经过一系列替换和移位后转换成完全不同的64位输出数据。

import binascii
from Cryptodome.Cipher import DES


key = b'12345678'	# 密钥(只能是8位)
iv = b'12345678'	# 初始化向量

# 创建了一个DES加密对象
cipher1 = DES.new(key, DES.MODE_CFB, iv)

# 需要加密的数据
data = '大家好,我是啊啊啊'.encode()

# 加密过程
msg = cipher1.encrypt(data)

# 创建了一个解密对象(加密解密不能使用同一把密钥)
cipher2 = DES.new(key, DES.MODE_CFB, iv)

# 解密过程
print(cipher2.decrypt(msg).decode())
复制代码

1.2,3DES

特点:比DES更加安全,更强,通过增加密钥长度(计算机运行能力增强)

简介:

3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。

由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解。3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样:

3DES加密过程为:C=Ek3(Dk2(Ek1(M)))

3DES解密过程为:M=Dk1(EK2(Dk3(C)))

# 与DES不同的就是他的密钥
key = b'123456781234567812345678'	# 密钥(DES只能是8位,3DES就是24位)
复制代码

1.3,AES

特点:抵抗暴力破解强度高,密钥长度长,当前互联网使用范围广

简介:

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

AES在软件及硬件上都能快速地加解密,相对来说较易于实作,且只需要很少的存储器。作为一个新的加密标准,目前正被部署应用到更广大的范围。

特点与思想

  1. 抵抗所有已知的攻击。

  2. 在多个平台上速度快,编码紧凑。

  3. 设计简单。

AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同。

一般常用的是128位

from Cryptodome.Cipher import AES
from Cryptodome import Random
from binascii import b2a_hex

# 要加密的明文
data = '测试数据'

# 密钥 key 长度必须是 16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.
# 目前AES-128
key = b'this is a 16 key'

# 生成长度等于AES快大小的不可重复的密钥向量
iv = Random.new().read(AES.block_size)

# 加密函数,使用 key 和 iv 创建,使用 MODE_CFB 模式
myencrypt = AES.new(key, AES.MODE_CFB, iv)

# 加密的明文长度必须为16的倍数,如果长度不为16的倍数,则需要补足为16的倍数
# 将iv(密钥向量)加到加密的密文开头,一起传输
encrypttext = iv + myencrypt.encrypt(data.encode())

# 解密函数,要用 key 和 iv(密文前16位) 生成新的AES对象
mydecrypt = AES.new(key, AES.MODE_CFB, encrypttext[:16])

# 使用新生成的 AES 对象,讲加密的密文解密
decrypttext = mydecrypt.decrypt(encrypttext[16:])

print('密钥key为:', key)
print('iv为:', b2a_hex(encrypttext)[:16])
print('加密后的数据为:', b2a_hex(encrypttext)[16:])
print('加密后的数据为:', decrypttext.decode())
复制代码

1.4,PyCrytodemo

PyCryptoPython 中密码学方面最有名的第三方软件包。可惜的是,它的开发工作于2012年就已停止

幸运的是,有一个该项目的分支 PyCrytodome 取代了 PyCrypto

PyCrypto文档: pycryptodome.readthedocs.io/en/latest/s…

  1. 安装与导入

    • Linux

      # 安装
      pip install pycryptodome
      
      # 导入
      import Crypto 
      复制代码
    • Windows

      安装之前需要先安装Microsoft Visual c++ 2015

      # 安装有稍稍的不同(pycryptodomex是代表两个版本都下载共存)
      pip install pycryptodomex
      
      # 导入
      import Cryptodome
      复制代码

二,非对称加密

指的是加密和解密使用不同的密钥。公钥服务器提供,私钥保存在服务器,密码的加密

2.0,简介

指的是加密和解密使用不同的秘钥。

一把作为公开的公钥,另一把作为私钥。这对密钥中的公钥进行加密,私钥用于解密。反之亦然(被私钥加密的数据也可以被公钥解密) 。

在实际使用中私钥一般保存在发布者手中,是私有的不对外公开的,只将公钥对外公布,就能实现只有私钥的持有者才能将数据解密的方法。 这种加密方式安全系数很高,因为它不用将解密的密钥进行传递,从而没有密钥在传递过程中被截获的风险,而破解密文几乎又是不可能的。

但是算法的效率低,所以常用于很重要数据的加密,常和对称配合使用,使用非对称加密的密钥去加密对称加密的密钥。

事实上,公钥加密算法很少用于数据加密,它通常只是用来做身份认证,因为它的密钥太长,加密速度太慢--公钥加密算法的速度甚至比对称加密算法的速度慢上3个数量级(1000倍)。

主要作用:

通常用于保证身份验证。

常用的公钥加密算法有:

  • RSA: 可以实现数字签名 和 数据加密
  • DSA: 只能实现数字签名,不能实现数据加密

特点:

  1. 加密与解密使用的不同的密钥。
  2. 实际上它所使用的密钥是一对儿,一个叫公钥,一个叫私钥。这对密钥不是独立的,公钥是从私钥中提炼出来,因此私钥是很长的,968位、1024位、2048位、4096位的都有。
  3. 通常公钥是公开的,所有人都可以得到;私钥是不能公开的,只有自己才有。
  4. 用公钥机密的内容只能用与之对应的私钥才能解密,反之亦然。

2.1,RSA

RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的。 RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

首先安装 RAS 模块

pip install rsa
复制代码

而且,因为RSA加密算法的特性,RSA的公钥私钥都是10进制的,但公钥的值常常保存为16进制的格式,所以需要将其用int()方法转换为10进制格式。

用网页中的公钥把数据加密

# -.- encoding = utf-8 -.-
import rsa
import binascii
# rsa 加密,公钥都是由服务器提供的

# 使用网页中获得的n和e值,将明文加密
def rsa_encrypt(rsa_n, rsa_e, message):
    # 用 n 和 e 生成公钥
    key = rsa.PublicKey(rsa_n, rsa_e)
    # 用公钥加密明文
    message = rsa.encrypt(message.encode(), key)
    # 讲密文转换成可读性高的十六进制
    message = binascii.b2a_hex(message)
    # 将加密结果转化回字符串并返回
    return message.decode()


# RSA的公钥有两个值 n 和 e,我们在网站中获得的值一般就是这两个
pubkey_n = '8d7e6949d411ce14d7d233d7160f5b2cc753930caba4d5ad24f923a505253b9c39b09a059732250e56c594d735077cfcb0c3508e9f544f101bdf7e97fe1b0d97f273468264b8b24caaa2a90cd9708a417c51cf8ba35444d37c514a0490441a773ccb121034f29748763c6c4f76eb0303559c57071fd89234d140c8bb965f9725'
pubkey_e = '10001'
# 需要将十六进制转换成十进制
rsa_n = int(pubkey_n, 16)
rsa_e = int(pubkey_e, 16)
# 要加密的明文
message = '测试数据'

if __name__ == '__main__':
    print('公钥n的值的长度:', len(pubkey_n))
    print('加密后的数据:', rsa_encrypt(rsa_n, rsa_e, message))
复制代码

三,hash

主要用来验证数据的完整性

3.0,简介

单向加密是指只能对明文数据进行加密,而不能解密数据。

举个例子:每个人都有不同的指纹,看到这个人,可以得出他的指纹等信息,并且唯一对应,但你只看一个指纹,是不可能看到或读到这个人的长相或身份等信息。

常用的算法实现:

  • MD5: 128bits
  • SHA: SHA1(160bits), SHA224, SHA256, SHA384

特点:

  1. 不可逆:无法根据数据指纹/特征码还原原来的数据。
  2. 容易计算:从原数据计算出MD5值很容易。
  3. 抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
  4. 定长输出:任意长度的数据,算出的MD5值长度都是固定的。

3.2,MD5,SHA

由于MD5模块在python3中被移除,在python3中使用hashlib模块进行md5操作

# -。- encoding = utf-8 -.-
import hashlib

data = '测试数据'

text = hashlib.md5()

text.update(data.encode())

print('MD5加密前的数据:', data)
print('MD5加密后的数据:', text.hexdigest())
print('MD5加密后的长度:', len(text.hexdigest()))
复制代码
MD5加密前的数据: 测试数据
MD5加密后的数据: 145314895749100ae8306079519b3393
MD5加密后的长度: 32
复制代码

MD5长度

md5的长度,默认为128bit,也就是128个0和1的二进制串。这样表达是很不友好的。所以将二进制转成了16进制,每4个bit表示一个16进制,所以128/4 = 32 换成16进制表示后,为32位了。

猜你喜欢

转载自blog.csdn.net/weixin_73136678/article/details/128905162