SM4分组密码算法,原名SMS4,国家密码管理局于2012年3月21日发布,相关标准为“GM/T 0002-2012《SM4分组密码算法》(原SMS4分组密码算法)”。它是一种分组对称加密算法,分组长度和密钥长度均为 128bit ,加密算法与密码扩展算法均采用 32 轮非线性迭代结构, Sbox 为固定的 8bit 输入 8bit 输出的置换。 数据加/解密的算法结构相同,只是轮密钥的使用顺序相反,解密轮密钥是加密轮密钥的逆序。
SBox
在密码学中,Sbox(Substitution-box,替换盒)是对称密钥加密算法执行替换计算的基本结构。SBox接受一个特定位数的输入,通过查表将其转换为特定位数的输出。SM4 给定的 SBox 如下:
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
| 0 |
D6 |
90 |
E9 |
FE |
CC |
E1 |
3D |
B7 |
16 |
B6 |
14 |
C2 |
28 |
FB |
2C |
05 |
| 1 |
2B |
67 |
9A |
76 |
2A |
BE |
04 |
C3 |
AA |
44 |
13 |
26 |
49 |
86 |
06 |
99 |
| 2 |
9C |
42 |
50 |
F4 |
91 |
EF |
98 |
7A |
33 |
54 |
0B |
43 |
ED |
CF |
AC |
62 |
| 3 |
E4 |
B3 |
1C |
A9 |
C9 |
08 |
E8 |
95 |
80 |
DF |
94 |
FA |
75 |
8F |
3F |
A6 |
| 4 |
47 |
07 |
A7 |
FC |
F3 |
73 |
17 |
BA |
83 |
59 |
3C |
19 |
E6 |
85 |
4F |
A8 |
| 5 |
68 |
6B |
81 |
B2 |
71 |
64 |
DA |
8B |
F8 |
EB |
0F |
4B |
70 |
56 |
9D |
35 |
| 6 |
1E |
24 |
0E |
5E |
63 |
58 |
D1 |
A2 |
25 |
22 |
7C |
3B |
01 |
21 |
78 |
87 |
| 7 |
D4 |
00 |
46 |
57 |
9F |
D3 |
27 |
52 |
4C |
36 |
02 |
E7 |
A0 |
C4 |
C8 |
9E |
| 8 |
EA |
BF |
8A |
D2 |
40 |
C7 |
38 |
B5 |
A3 |
F7 |
F2 |
CE |
F9 |
61 |
15 |
A1 |
| 9 |
E0 |
AE |
5D |
A4 |
9B |
34 |
1A |
55 |
AD |
93 |
32 |
30 |
F5 |
8C |
B1 |
E3 |
| A |
1D |
F6 |
E2 |
2E |
82 |
66 |
CA |
60 |
C0 |
29 |
23 |
AB |
0D |
53 |
4E |
6F |
| B |
D5 |
DB |
37 |
45 |
DE |
FD |
8E |
2F |
03 |
FF |
6A |
72 |
6D |
6C |
5B |
51 |
| C |
8D |
1B |
AF |
92 |
BB |
DD |
BC |
7F |
11 |
D9 |
5C |
41 |
1F |
10 |
5A |
D8 |
| D |
0A |
C1 |
31 |
88 |
A5 |
CD |
7B |
BD |
2D |
74 |
D0 |
12 |
B8 |
E5 |
B4 |
B0 |
| E |
89 |
69 |
97 |
4A |
0C |
96 |
77 |
7E |
65 |
B9 |
F1 |
09 |
C5 |
6E |
C6 |
84 |
| F |
18 |
F0 |
7D |
EC |
3A |
DC |
4D |
20 |
79 |
EE |
5F |
3E |
D7 |
CB |
39 |
48 |
例如,对于输入 EF, 通过查表输出为 第 E 行,第 F 列,84
继续阅读
最近做了一些与密码学相关的工作,对于消息的加解密有了一些新的看法。结合之前项目中遇到的服务端密码存储的问题,在这里写一点自己的想法。
目前常见的一些密码存储方式
以下是一些常见的密码存储方式,其中一部分是自己用过的,一部分是见过别人使用的:
- 明文
pwd
- 经过MD5 哈希后存储
md5(pwd)
- 两次MD5后存储
md5(md5(pwd))
- 加盐md5存储
md5(pwd + salt)
- 密码扩展后存储
kdf(pwd)
- 慢哈希后存储
brypt(pwd)
- 以上多种算法组合后存储
哈希
很明显,第 1 种是最不安全的。存储在数据库中的密码可以轻易地被管理员看到。一旦服务器被拖库,这些密码就轻易地被别人窃取,并可以根据账号和密码在其它网站上试探(大部分用户在多个网站上使用相同的用户名和密码)。尽管人人都知道这种存储方式是极不安全的,但仍然有很多网站使用它。如前几年震惊中外的 CSDN 拖库事件 。在这一事件中,有600万用户的信息被泄漏。
第 2 种 方式比较古老,管理员和黑客无法看到用户的明文密码。但如我们所知,MD5 是不安全的。如 MD5 碰撞算法。而在此之前,查表法一直做为破解 MD5 密码的重要手段 。 所谓 查表法 ,就是对字典(密码集) 进行 MD5 运算,将哈希值预存储在一个或多个表里。

当需要破解某密码时,根据服务器存储的哈希值在预计算的哈希值表中查找对应的值。而 反向查表法 ,攻击者可以同时对多个重合密码进行攻击。
SELECT table_b.pwd, table_user.uname FROM table_user,table_b WHERE table_b.hash_val = 'hash_val_1' ; -- 查表
SELECT table_b.pwd, table_user.uname FROM table_user,table_b WHERE table_user.hash_val = 'hash_val_x' ;. --反向查表
如果用户使用了弱密码,这种使用反向查表法来破解密码简直不要太轻松。
使用查表法需要存储字典与哈希值,对存储空间有较高的要求。后来进化出了 彩虹表 法,在算法的空间和时间上进行了优化。
加盐
第 3、4 种方式针对上述攻击方法做了改进。其实第 3 种方式并大的改进, 因为算法和参数是固定的。而第 4 种的改进比较好。所谓 加盐(salt) ,即在消息的任意固定位置添加附加消息。它使攻击者的字典变得更加复杂,攻击者计算预存储值的难度大大增加了;每个密码都混入了不同的盐,所以使得反向查表法去批量匹配密码变得难以施行。在加盐存储的实践中,有部分人使用了错误的实现:如盐值过短,或盐值重复。
盐值过短 无法对攻击者造成足够的困扰,一个好的盐值的长度起码要和哈希值的长度一至。而 盐值重复 则和未加盐没有区别:两个相同的密码加相同的盐,得到的哈希值是一样的。特别是对于那些将盐值硬编码到代码里的,简直是在为攻击者提供帮助。类似地,也不要使用用户名、用户id、创建时间等字段做为盐值–盐值应该是随机的,且并用户修改密码时应该给出新的盐值。
继续阅读