Python 将linux sha512阴影转换为十六进制

Python 将linux sha512阴影转换为十六进制,python,linux,encryption,hash,sha512,Python,Linux,Encryption,Hash,Sha512,我试图理解linux阴影字符串格式,并将字符串转换为通用十六进制格式,就像MD5通常的表示方式一样 我遵循这里的定义 如上所述,最后一步(步骤22)是特殊的base-64编码,具有重新排序的字节 我编写了一个python脚本(我的第一个python程序)来解码base64,然后将其恢复到原始顺序 但是问题是,结果与通常的SHA1哈希不同 例如,带有salt“456”的密码“123”(不带引号)将生成一个影子字符串 $6$456$yTSeWYNbvZDCsuZIN.Qdeg.0DXY5N1XDD

我试图理解linux阴影字符串格式,并将字符串转换为通用十六进制格式,就像MD5通常的表示方式一样

我遵循这里的定义

如上所述,最后一步(步骤22)是特殊的base-64编码,具有重新排序的字节

我编写了一个python脚本(我的第一个python程序)来解码base64,然后将其恢复到原始顺序

但是问题是,结果与通常的SHA1哈希不同

例如,带有salt“456”的密码“123”(不带引号)将生成一个影子字符串

$6$456$yTSeWYNbvZDCsuZIN.Qdeg.0DXY5N1XDDPO7QGFQJNZOQY5QXIEMM7PDQYWIG6Y3PSH5EYQJ21FWRJHJE/

在我的程序中,它生成

A922F952190B1ED9AD9EFEDA918472364A10CABDBE79D7B5EA52A4FA6691B6A7648D429AB7BED45C7F7FE9938B8C0084F3025365C1FDC968A145192767D566A

但是,123456和456123的SHA512散列是

BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413

CA3D1DE02C4B15D2E95521E259C5E08AA8FEAA722BA1401460524EFE3F248DB3D98AA7C4ACCBE887E1B40573D7EBA71017C5DF029C16C8D6F06B0FFDA310

没有一个和我的结果一样。那么,我对阴影生成方法有什么理解错误吗?还是我的代码有问题

my python代码(输入应为base64代码,即阴影字符串最后一个“$”后的字符串):

#/usr/bin/python
#文件名:conv.py
导入系统
b64s=“./0123456789abcdefghijklmnopqrstuvxyzabefghijklmnopqrstuvxyz”
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_输入('输入一个阴影字符串:')
ba=[0]*64
巴乌组织=[0]*64
对于范围(0,21)内的i:
字节24=0
对于范围(0,4)内的j:
字节24+=(b64s.find(sd_str[i*4+j])>(j*8))&0x0000FF)

byte24=b64s.find(sd_str[84])+(b64s.find(sd_str[85])您缺少的最大一点是影子文件中的密码哈希被迭代。密码
123
的哈希值不是
sha(password+salt)
,而是
sha(sha(password+salt)+salt)
,默认情况下有5000个嵌套级别。

sha256\u crypt算法不仅仅是一个sha256散列,它本身就是一个相当复杂的构造,恰好使用sha256作为加密原语,因此得名

rounds值不仅需要SHA256函数的多个组合,它甚至不是
SHA256(SHA256(…)
,而是一个更复杂的循环,事先有许多额外的设置步骤……其目标是使它比简单的
SHA256()更适合密码哈希
。也就是说,编码到base64之前的换位,以及自定义base64编码,并没有真正增加任何安全方面的内容,只是让实现变得更加困难


我建议阅读Akkdia.org文档的其余部分,该文档准确地描述了阴影散列的计算方式。或者,您可以查看Passlib项目的源代码,其中显示了您需要实现的内容—查找
raw_sha256_crypt()
函数,这是正确的起点,尽管肉在
raw\u sha\u crypt()
中。请注意,我将您链接到了v1.5.3源代码,因为也有点难理解。

谢谢duskwuff。我认为如果重复哈希,级别数应该在salt字符串的开头表示为round,即“rounds=5000$”如果未指定轮数,则默认为5000.confirfied,crypt.crypt(“123”,“$6$rounds=5000$456$”==crypt.crypt(“123”,“$6$456$”)非常感谢。
#!/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()