我正在尝试理解linux阴影字符串格式,并将字符串转换为通用十六进制格式,就像通常表示MD5一样。
我遵循这里的定义 http://www.akkadia.org/drepper/SHA-crypt.txt
如上所述,最后一步(步骤22)是一个特殊的base-64编码,具有重新排序的字节。
我编写了一个python脚本(我的第一个python程序)来解码base64,然后将其恢复到原始顺序。
但问题是,结果与通常的SHA1哈希值不同。
例如,使用盐“456”的密码“123”(不含引号)将生成阴影字符串
$ 6 $ 456 $ yTSeWYNbvZDCsuZIN.Qdeg.0DxY5N1XddpO7qgFqjnZOqpy5QXIeMM7pdQYWIgu6Y3pSh5eYqJ21fqrlrjhJe /
使用我的程序,它会生成
A922F952190B1ED9ADD9EFEDA918472364A10CABDBE79D7B5EA52A4FA6691B6A7648D429AB7BED45C7F7FE9938B8C0084F3025365C1FDC968A145192767D566A
然而,123456和456123的SHA512散列是
BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413
CA3D1DDE02C4B15D2E95521E259C5E08AAEA8FEAA722BA14014605249EFE3F248DB3D98AA7C4ACCBE887E1B40573D7EBA71017C5DF029C16C8D6F06B0FFDA310
它们都不是我的结果。那么,阴影生成方法有什么我理解的错误吗?或者我的代码出了什么问题?
我的python代码(输入应该是base64代码,即影子字符串的最后一个“$”之后的字符串):
#!/usr/bin/python
# filename: conv.py
import sys
b64s = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
bm = ( \
(0,21,42), \
(22,43,1), \
(44,2,23), \
(3,24,45), \
(25,46,4), \
(47,5,26), \
(6,27,48), \
(28,49,7), \
(50,8,29), \
(9,30,51), \
(31,52,10), \
(53,11,32), \
(12,33,54), \
(34,55,13), \
(56,14,35), \
(15,36,57), \
(37,58,16), \
(59,17,38), \
(18,39,60), \
(40,61,19), \
(62,20,41), \
('*','*',63))
sd_str = raw_input('Enter a Shadow String: ')
ba = [0]*64
ba_org = [0]*64
for i in range (0,21):
byte24 = 0
for j in range(0,4):
byte24 += (b64s.find(sd_str[i*4+j]) << (j*6))
for j in range(0,3):
ba[bm[i][2-j]] = ((byte24>>(j*8))&0x0000FF)
byte24 = b64s.find(sd_str[84]) + (b64s.find(sd_str[85])<<6)
ba[63] = byte24 #last byte
for i in range (0,64):
sys.stdout.write('%02X' % ba[i])
sys.stdout.write('\n')
sys.stdout.flush()
答案 0 :(得分:2)
您最不想要的是重复使用影子文件中的密码哈希。密码123
的哈希值不是sha(password + salt)
,而是sha(sha(sha(sha(password + salt) + salt) + salt)...)
,默认情况下有5000个嵌套级别。
答案 1 :(得分:1)
“sha256_crypt”算法不仅仅是一个SHA256哈希 - 它本身就是一个相当复杂的构造,它恰好使用SHA256作为加密原语,因此得名。
舍入值不仅要求SHA256函数的多个组合,它甚至不是sha256(sha256(...))
,而是一个更复杂的循环,事先有许多额外的设置步骤......其目标是使它更适合密码散列而不仅仅是sha256()
。也就是说,在编码为base64之前的转置以及自定义的base64编码并没有真正添加任何安全性,它只会让实现更加困难。
我建议阅读Akkdia.org文档的其余部分,该文档准确描述了如何计算影子哈希。或者,您可以在Passlib项目的源代码中查看sha2_crypt.py,它显示了您需要实现的内容 - 查找raw_sha256_crypt()
函数,这是正确的起点,尽管肉是在{{ 1}}。请注意,我将您链接到v1.5.3源代码,因为latest version(虽然更快)也有点难以理解。