赞
踩
SM4分为加解密算法和密钥拓展算法,简单地说就是将128比特数据分为四组,使用轮函数对其进行运算,密钥拓展算法用于生成轮密钥,当使用密钥拓展算法时,轮函数输入为(四组输入数据,固定参数CK),当使用加密算法时轮函数输入为(四组输入数据,轮密钥rk),解密算法与加密算法相同只是使用的轮密钥顺序相反。
在本文中,明文和密钥及IV的输入都为16进制数,如果需要加密字符串类型的明文,需要先将其转为16进制,但在本文中仅针对明文为128bit时进行了实现,如果小于或大于128bit需要进行相应的填充。
异或可以表示为xor,在python中可以通过^实现,a与b的异或运算可以理解为(假设a和b为16进制),需注意python默认值是字符串比如,a = “01234567”,需要进行转码后进行运算。
a = int('01234567',16)
b = int('30',16)
print(bin(a^b))
#a的二进制值为0b1001000110100010101100111
#b的二进制值为0b110000
#输出的结果为:0b1001000110100010101010111
其实就是,首先将进行异或的数转为2进制,从低位开始比较,两者相同则该位改为0,两者不同该位改为1,如果a>b,那么将比较至b的最高位,剩余的未比较的位数值保持不变
GB-T 32907中对轮函数的描述很好理解,其中T为合成置换,包括一次S盒置换后将输出作为线性变换L的输入。
SBOX = ['d6', '90', 'e9', 'fe', 'cc', 'e1', '3d', 'b7', '16', 'b6', '14', 'c2', '28', 'fb', '2c', '05', '2b', '67', '9a', '76', '2a', 'be', '04', 'c3', 'aa', '44', '13', '26', '49', '86', '06', '99', '9c', '42', '50', 'f4', '91', 'ef', '98', '7a', '33', '54', '0b', '43', 'ed', 'cf', 'ac', '62', 'e4', 'b3', '1c', 'a9', 'c9', '08', 'e8', '95', '80', 'df', '94', 'fa', '75', '8f', '3f', 'a6', '47', '07', 'a7', 'fc', 'f3', '73', '17', 'ba', '83', '59', '3c', '19', 'e6', '85', '4f', 'a8', '68', '6b', '81', 'b2', '71', '64', 'da', '8b', 'f8', 'eb', '0f', '4b', '70', '56', '9d', '35', '1e', '24', '0e', '5e', '63', '58', 'd1', 'a2', '25', '22', '7c', '3b', '01', '21', '78', '87', 'd4', '00', '46', '57', '9f', 'd3', '27', '52', '4c', '36', '02', 'e7', 'a0', 'c4', 'c8', '9e', 'ea', 'bf', '8a', 'd2', '40', 'c7', '38', 'b5', 'a3', 'f7', 'f2', 'ce', 'f9', '61', '15', 'a1', 'e0', 'ae', '5d', 'a4', '9b', '34', '1a', '55', 'ad', '93', '32', '30', 'f5', '8c', 'b1', 'e3', '1d', 'f6', 'e2', '2e', '82', '66', 'ca', '60', 'c0', '29', '23', 'ab', '0d', '53', '4e', '6f', 'd5', 'db', '37', '45', 'de', 'fd', '8e', '2f', '03', 'ff', '6a', '72', '6d', '6c', '5b', '51', '8d', '1b', 'af', '92', 'bb', 'dd', 'bc', '7f', '11', 'd9', '5c', '41', '1f', '10', '5a', 'd8', '0a', 'c1', '31', '88', 'a5', 'cd', '7b', 'bd', '2d', '74', 'd0', '12', 'b8', 'e5', 'b4', 'b0', '89', '69', '97', '4a', '0c', '96', '77', '7e', '65', 'b9', 'f1', '09', 'c5', '6e', 'c6', '84', '18', 'f0', '7d', 'ec', '3a', 'dc', '4d', '20', '79', 'ee', '5f', '3e', 'd7', 'cb', '39', '48',]
GB-T 32907中给出的S盒数据为16进制,不过我们将在进行S盒置换时将数据转为10进制进行运算,所以不需要使用0X形式描写数据。
其中如果使用Oxd6形式描写数据,在转为10进制时直接使用int(0xd6)而不需添加进制参数,而使用“d6”描写数据时需要使用int(“d6”,16)。
其中B<<<2 表示为对B进行32位左移2,可以理解位将高位的两位移动到低位,输入和输出都为32位。
在一次针对128bit明文的加密过程中,密钥拓展算法将生成32个轮密钥。而密钥拓展算法的输入为128bit的密钥。
首先将16字节也就是128bit的密钥分为一个每4字节为一组的列表,这里可以使用如下方式进行分组,其中n为分组位数。
def group(list, n):
for i in range(0, len(list), n):
yield list[i:i + n]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。