des加密算法python代码_简化版的DES加密Python实现

本文通过Python实现S-DES加密算法。

在写程序的时候为了和资料上的函数名称一致,便于理解,有些函数、变量的命名不是很符合编程规范,也没有异常处理,主要用来加深理解S-DES算法。

算法说明

简化版DES(S-DES)的过程图示

S-DES加解密图示

加密过程

S-DES加密

简书书写公式不方便,上述公式用字符表示如下

秘文 = IPinv(fK(SW(fK(IP(明文)))))

设计

输入

等待加密的文字,以十六进制字符串输入

10位秘钥,以列表输入

输出

加密的字符,以十六进制字符表示

接口设计

# 加密

ciphertext = sdesEncrypt('59616e67', [0,1,0,1,1,1,1,1,0,1])

# 解密

plaintext = sdesDecrypt(ciphertext, [0,1,0,1,1,1,1,1,0,1])

实现

秘钥(key)变换

S-DES需要一个10位(bit)的秘钥。每位表述为k1,k2,k3,k4,k5,k6,k7,k8,k9,k10。

用到Shift、P10和P8三个函数

P10:对10位秘钥重排

P8:选取其中8位排列

Shift:循环左移1位

P10函数如下

P10(k1,k2,k3,k4,k5,k6,k7,k8,k9,k10) = (k3,k5,k2,k7,k4,k10,k1,k9,k8,k6)

P10函数实现

def P10(key):

k = [None] + key

return [k[3],k[5],k[2],k[7],k[4],k[10],k[1],k[9],k[8],k[6]]

编程语言的列表索引是从0开始,这里表述行位操作时,索引0存放无用值None,仅仅作占位用。从索引1开始存放数据。比如4位二进制1011存放到在长度为5的列表[None, 1, 0, 1, 1]中。这样的好处是代码的位索引和文本说明次序一致,后面代码有类似思路。

P8和Shift函数的实现

def P8(key):

k = [None] + key

return [k[6],k[3],k[7],k[4],k[8],k[5],k[10],k[9]]

def Shift(value):

return value[1:] + value[0:1]

S-DES 加解密1个字节

IP和 IPinv 函数

IP和IPinv互相为反函数,即:IPinv(IP(X)) = X,IP(IPinv(X)) = X

def IP(value):

v = [None] + value

return [k[2],k[6],k[3],k[1],k[4],k[8],k[5],k[7]]

def IPinv(value):

v = [None] + value

return [k[4],k[1],k[3],k[5],k[7],k[2],k[8],k[6]]

SW 函数

SW函数交换左边和右边的4位

def SW(value):

return value[4:] + value[:4]

fK函数

fK操作8位二进制,最左边的4位记作L,最右边的4位记作作R,表示如下

fK(L,R) = (L⊕F(R,K), R)

⊕是异或运算

K表示子秘钥K1或者K2

F函数是新引入的函数,可通过下面的两个步骤求出:

创建一个2行4列的表格P

对输入的4的位数字(n1,n2,n3,n4)

对输入K(k11,k12,k13,k14,k15,k16,k17,k18)

表格P的值如下

P(0,0) = n4 ⊕ k11

P(0,1) = n1 ⊕ k12

P(0,2) = n2 ⊕ k13

P(0,3) = n3 ⊕ n14

P(1,0) = n2 ⊕ k15

P(1,1) = n3 ⊕ k16

P(1,2) = n4 ⊕ k17

P(1,3) = n1 ⊕ k18

在盒中查找

有两个盒子S0和S1,值如下

S0 = [[1, 0, 3, 2],

[3, 2, 1, 0],

[0, 2, 1, 3],

[3, 1, 3, 2]]

S1 = [[0, 1, 2, 3],

[2, 0, 1, 3],

[3, 0, 1, 0],

[2, 1, 0, 3]]

P(0,0)和P(0,1)组合成二进制的值row0,比如P(0,0) = 1, P(0,1) = 0,则row0 = 二进制10 = 2

P(0,2)和P(0,3)组合成二进制的值col0

P(1,0)和P(1,1)组合成二进制的值row1

P(1,2)和P(1,3)组合成二进制的值col1

S0的第row0行col0列的值S0(row0,col0)表示成两位二进制v1,v2,类似地S1(row1,col1)表示成两位二进制v3,v4

(v2,v4,v3,v1)组合成的二进制的值便是F函数的值

fK函数和F函数实现

def F(value, key):

val = lambda x, y: x * 2 + y

highLow = lambda x: (1 if x & 0b10 > 0 else 0), (x & 0b01)

P = [[0, 0, 0, 0],

[0, 0, 0, 0]]

n = [None] + value

k = [None] * 11 + key # 这里前面空11无用的值None

P[0][0] = n[4] ^ k[11]

P[0][1] = n[1] ^ k[12]

P[0][2] = n[2] ^ k[13]

P[0][3] = n[3] ^ k[14]

P[1][0] = n[2] ^ k[15]

P[1][1] = n[3] ^ k[16]

P[1][2] = n[4] ^ k[17]

P[1][3] = n[1] ^ k[18]

row0 = val(P[0][0], P[0][1])

col0 = val(P[0][2], P[0][3])

row1 = val(P[1][0], P[1][1])

col1 = val(P[1][2], P[1][3])

v1, v2 = highLow(S0[row0][col0])

v3, v4 = highLow(S1[row1][col1])

return [v2, v4, v3, v1]

def fK(value, key):

L = value[:4]

R = value[4:]

return list(map(lambda x:x[0]^x[1], zip(L, F(R))) + R

加密单字节函数 sdesEncryptByte

用上文出现过的公式:秘文 = IPinv(fK(SW(fK(IP(明文)))))

代码实现

def sdesEncryptByte(value, key):

K1 = P8(Shift(P10(key)))

K2 = P8(Shift(Shift(P10(key))))

fK1Value = fK(IP(value), K1)

swValue = SW(fK1Value)

fK2Value = fK(swValue, K2)

return IPinv(fK2Value)

解密单字节函数 sdesDecryptByte

代码实现

def sdesDecryptByte(value, key):

K1 = P8(Shift(P10(key)))

K2 = P8(Shift(Shift(P10(key))))

fK2Value = fK(IPinv(value), K2)

swValue = SW(fK2Value)

fK1Value = fK(swValue, K1)

return IP(fK1Value)

S-DES加密

使用了一个辅助函数makeByteList,把十六进制文本转化成字节数组,每个字节又是一个数组。

def makeByteList(hextext):

l = list(hextext)

arr = []

for i in range(len(l) // 2):

arr += [ l[2*i] + l[2*i+1] ]

binaryList = []

for value in arr:

text = list(bin(int(value, 16))[2:].zfill(8))

binaryList += [text]

def sdesEncrypt(hextext, key):

encryptedString = ''

for value in makeByteList(hextext)

encryptedByte = sdesEncryptByte(value, key)

encryptedString += encryptedByte

def sdesDecrypt(hextext, key):

encryptedString = ''

for value in makeByteList(hextext)

encryptedByte = sdesDecryptByte(value, key)

encryptedString += encryptedByte

相关文章

参考文献

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值