shadow文件结构
user:$6$X2w.CbqR$IH83vciPhgj.85yU33iS3m4fWf3gTGDxwg7EbUkt/XvhwZd/UAz9dxXzFzEx/dbpwG.cYCmm9yw8Lgp0:18731:0:99999:7:::
使用冒号分割,第一个字段是用户名,第二个字段是密码hash。
密码hash使用$分割为3部分,以此为例:
密码hash字段结构
$6$X2w.CbqR$IH83vciPhgj.85yU
$6
标识使用第6种加密模式,即SHA-512
$X2w.CbqR
是加密盐值salt
$IH83vciPhgj.85yU……
是密码hash。
密码hash的计算方法
计算方法为sha512(password,"$6$slat
")
以下python程序保存后,可直接调用crypt算法执行加密。
python crypt.py --sha-512
#! /usr/bin/python
'''Generate encrypted passwords for GRUB.'''
import crypt
import getopt
import getpass
import sys
def usage():
'''Output usage message to stderr and exit.'''
print >> sys.stderr, 'Usage: grub-crypt [OPTION]...'
print >> sys.stderr, 'Try `$progname --help\' for more information.'
sys.exit(1)
def gen_salt():
'''Generate a random salt.'''
ret = ''
with open('/dev/urandom', 'rb') as urandom:
while True:
byte = urandom.read(1)
if byte in ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
'./0123456789'):
ret += byte
if len(ret) == 16:
break
return ret
def main():
'''Top level.'''
crypt_type = '$6$' # SHA-256
try:
opts, args = getopt.getopt(sys.argv[1:], 'hv',
('help', 'version', 'md5', 'sha-256',
'sha-512'))
except getopt.GetoptError, err:
print >> sys.stderr, str(err)
usage()
if args:
print >> sys.stderr, 'Unexpected argument `%s\'' % (args[0],)
usage()
for (opt, _) in opts:
if opt in ('-h', '--help'):
print (
'''Usage: grub-crypt [OPTION]...
Encrypt a password.
-h, --help Print this message and exit
-v, --version Print the version information and exit
--md5 Use MD5 to encrypt the password
--sha-256 Use SHA-256 to encrypt the password
--sha-512 Use SHA-512 to encrypt the password (default)
Report bugs to <bug-grub@gnu.org>.
EOF''')
sys.exit(0)
elif opt in ('-v', '--version'):
print 'grub-crypt (GNU GRUB 0.97)'
sys.exit(0)
elif opt == '--md5':
crypt_type = '$1$'
elif opt == '--sha-256':
crypt_type = '$5$'
elif opt == '--sha-512':
crypt_type = '$6$'
else:
assert False, 'Unhandled option'
password = getpass.getpass('Password: ')
password2 = getpass.getpass('Retype password: ')
if not password:
print >> sys.stderr, 'Empty password is not permitted.'
sys.exit(1)
if password != password2:
print >> sys.stderr, 'Sorry, passwords do not match.'
sys.exit(1)
salt = crypt_type + gen_salt()
#salt="$6$salt"
#password=" your password"
print crypt.crypt(password, salt)
if __name__ == '__main__':
main()