2

我试图了解 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()
4

2 回答 2

2

您缺少的最重要的事情是影子文件中的密码哈希是迭代的。密码的哈希值123不是sha(password + salt),而是sha(sha(sha(sha(password + salt) + salt) + salt)...),默认嵌套 5000 级。

于 2013-01-23T07:24:02.183 回答
1

“sha256_crypt”算法不仅仅是一个 SHA256 哈希 - 它是一个相当复杂的结构,它恰好使用 SHA256 作为加密原语,因此得名。

rounds 值不仅需要 SHA256 函数的多个组合,它甚至不是sha256(sha256(...)),而是一个更复杂的循环,预先有许多额外的设置步骤......其目标是使其更适合密码散列比简单sha256()。也就是说,编码为 base64 之前的转置和自定义 base64 编码并没有真正增加任何安全性,它只是让实现起来更加痛苦。

我建议阅读 Akkdia.org 文档的其余部分,该文档准确描述了影子哈希的计算方式。或者,您可以查看Passlib项目源代码中的 sha2_crypt.py,它显示了您需要实现的内容 - 查找raw_sha256_crypt()函数,这是正确的起点,尽管内容位于raw_sha_crypt(). 请注意,我将您链接到 v1.5.3 源代码,因为最新版本(虽然速度更快)也有点难以理解。

于 2013-01-23T16:27:21.197 回答