暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

密码学基础-对称密码及其python实现

zero1安全笔记 2021-10-21
1217

最近搞免杀,用到一些密码加密知识,开个专栏记录一下,重新学习密码学(大二修过,忘得差不多了),参考书籍《图解密码技术》。

本文不追求密码算法细节,只记录密码算法基本原理,以及python实现加解密。


对称密码-相同的密钥加密解密


主要内容:DES、3DES、AES

比特序列:计算机的操作对象,由0和1组成。无论图片还是视频,亦或是程序,在计算机中都是以比特序列的形式存储。

XOR(异或)运算:规则简单来说就是:相同为0,不同为1

0 XOR 0 = 0

0 XOR 1 = 1

1 XOR 0 = 1

1 XOR 1 = 0

如果对比特序列进行异或运算(相同位数),进行逐一对各个比特进行计算,得到一个新的比特序列。根据运算规则,两个相同的数进行异或运算,结果一定为0,A xor A = 0。如果A xor B = C,那么C xor B = A,凭借这一特性,我们可以选择一个合适B,就可以利用XOR实现一个高强度的密码,A相当于明文,B是密钥,C是密文。在免杀中,可以使用XOR对shellcode进行编码,破坏特征,使用时再进行一次XOR运算,让shellcode正常运行。


DES加密


DES是1977年美国联邦信息处理标准中所采用的一种对称密码,一直以来被政府和银行广泛使用。随着计算机的进步,DES已经能够被破解,变得不在安全,现在已经被淘汰。


加解密过程


DES是一种将64比特明文加密成64比特密文的对称加密算法,密钥长度为56比特(从规格上来说,密钥是64比特,但由于每隔7比特会设置一个用于错误检查的比特,因此实质密钥长度为56比特)。DES以64比特明文(比特序列)为一个单位进行加密,这个单位称为分组,DES每次只能加密64比特的数据,如果明文过长,需要对DES加密进行迭代,迭代的具体方式称为模式(例如ECB、CBC)。

DES结构

DES结构称为Feistel网络(由Horst Feistel设计)在Feistel网络中,加密的各个步骤称为轮,整个加密过程就是进行若干次轮的循环,DES就是一种16轮循环的Feistel网络。下图为DES Feistel网络的一轮。

一轮的具体计算步骤:

1.将输入的数据分为左右两个部分。

2.将输入的右侧直接发送到输出的右侧。

3.将输入的右侧发送到轮函数。

4.论函数根据右侧数据和子密钥,计算出一串看上去是随机的比特序列。

5.将上一步得到的比特序列与左侧数据进行XOR运算,将结果作为加密后的左侧。

下一轮加密时,上一轮加密的左侧变成右侧,未加密的右侧变成左侧(左变右,右变左),再进行加密,循环16轮。


python实现


使用PyCryptodome实现,PyCryptodome是一个加密算法库,安装PyCryptodome

pip install pycryptodome

实现代码

# -*- coding:UTF-8 -*-
from Crypto.Cipher import DES #导入DES模块


key = b'zero1sec' #密钥,需要转换为二进制
text="this is des!" #明文
def judge(text): #判断text是否为8的倍数,text必须是8的倍数,如果不是就补足
while len(text) % 8 != 0:
text += ' '
return text
des = DES.new(key, DES.MODE_ECB) #创建DES实例,模式为ECB
fin_text = judge(text) #调用judge判断文本
print(fin_text,"|") #打印调整后的文本,“|”为分隔符
encode_text = des.encrypt(fin_text.encode("utf-8")) #进行加密
print(encode_text) #输出密文
decode_text = des.decrypt(encode_text).decode().rstrip(' ') #进行解密,使用rstrip去除末尾多余空白字符
print(decode_text) #输出明文


三重DES加密


由于DES已经能够被暴力破解,出于这个目的,三重DES被开发了出来。三重DES是将DES重复三次所得到的一种密码算法,也称为TDEA,通常缩写为3DES。但三重DES并不是简单的DES堆加,而是一个加密-解密-加密的过程,如下图

如果密钥1和密钥3相同,密钥2不同,称为DES-EDE2;如果三个密钥都不同就称为DES-EDE3,解密的过程和加密相反。


python实现代码

(本代码来源于网络)


# -*- coding:UTF-8 -*-
from Crypto.Cipher import DES3
import base64


class EncryptDate:
def __init__(self, key):
self.key = key # 初始化密钥
self.length = DES3.block_size # 初始化数据块大小
self.aes = DES3.new(self.key, DES3.MODE_ECB) # 初始化AES,ECB模式的实例
# 截断函数,去除填充的字符
self.unpad = lambda date: date[0:-ord(date[-1])]


def pad(self, text):
"""
#填充函数,使被加密数据的字节码长度是block_size的整数倍
"""
count = len(text.encode('utf-8'))
add = self.length - (count % self.length)
entext = text + (chr(add) * add)
return entext


def encrypt(self, encrData): # 加密函数
res = self.aes.encrypt(self.pad(encrData).encode("utf8"))
msg = str(base64.b64encode(res), encoding="utf8")
# msg = res.hex()
return msg


def decrypt(self, decrData): # 解密函数
res = base64.decodebytes(decrData.encode("utf8"))
# res = bytes.fromhex(decrData)
msg = self.aes.decrypt(res).decode("utf8")
return self.unpad(msg)


if __name__ == '__main__':
cr = EncryptDate('qaqaweqawqwertyuiopasdtf') #密钥24位
cr_res = cr.encrypt('zero1zerggsdgro3') #明文
print(cr_res)
de_res = cr.decrypt(cr_res)
print(de_res)


AES加密


AES是取代DES的成为新标准的一种对称算法,是经过公开竞选选出的一种算法。现在的AES标准是Rijndael算法,由多个轮构成,每一轮分为SubBytes、ShiftRows、MinColumns和AddRoundKey共四个步骤,AES是SPN结构。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同,如下表所示

AES

密钥长度(32位比特字)

分组长度(32位比特字)

加密轮数

AES-128

4

4

10

AES-192

6

4

12

AES-256

8

4

14

如果想研究AES的细节实现,可以参考:https://blog.csdn.net/qq_28205153/article/details/55798628


python代码实现


# -*- coding:UTF-8 -*-
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
from Crypto.Random import get_random_bytes


data = b"zero1sec" #明文
key = get_random_bytes(16) # 随机生成16字节(即128位)的加密密钥
cipher = AES.new(key, AES.MODE_CBC) # 实例化加密,使用CBC模式
encrypted_data = cipher.encrypt(pad(data, AES.block_size)) # 加密,pad函数用于分组和填充
print(encrypted_data) # 输出密文


#解密
de_cipher = AES.new(key, AES.MODE_CBC, cipher.iv) #实例化解密
data = unpad(de_cipher.decrypt(encrypted_data), AES.block_size) #解密
print(data) #输出明文


文章转载自zero1安全笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论