Forked from
DM / dm-docs
261 commits behind, 496 commits ahead of the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
cryptUtility.py 3.00 KiB
#!/usr/bin/env python
import random
import string
import crypt
#import md5
import hashlib
import base64
class CryptUtility:
CRYPT_TYPE = 6 # SHA-512 (man crypt)
SALT_CHARACTERS = string.lowercase + string.uppercase + string.digits
SALT_DELIMITER = '$'
SALT_LENGTH_IN_BYTES = 4
PBKDF2_ENCRYPTION = 'sha1' # use SHA-1 for compatibility with java
PBKDF2_KEY_LENGTH_IN_BYTES = 24
PBKDF2_ITERATIONS = 1003
@classmethod
def getRandomWord(cls, length):
return ''.join(random.choice(CryptUtility.SALT_CHARACTERS) for i in range(length))
@classmethod
def cryptPassword(cls, password):
""" Return crypted password. """
#calculator = md5.md5()
#calculator.update(salt)
#md5Salt = calculator.hexdigest()
#return crypt.crypt(cleartext, md5Salt)
salt = CryptUtility.getRandomWord(CryptUtility.SALT_LENGTH_IN_BYTES)
salt = '%s%s%s%s%s'.format(CryptUtility.SALT_DELIMITER, CryptUtility.CRYPT_TYPE, CryptUtility.SALT_DELIMITER, salt, CryptUtility.SALT_DELIMITER)
return crypt.crypt(password, salt)
@classmethod
def verifyPassword(cls, password, cryptedPassword):
""" Verify crypted password. """
return cryptedPassword == crypt.crypt(password, cryptedPassword)
@classmethod
def cryptPasswordWithPbkdf2(cls, password):
""" Crypt password with pbkdf2 package and encode with b64. """
salt = CryptUtility.getRandomWord(CryptUtility.SALT_LENGTH_IN_BYTES)
return cls.saltAndCryptPasswordWithPbkdf2(password, salt)
@classmethod
def saltAndCryptPasswordWithPbkdf2(cls, password, salt):
""" Crypt salted password with pbkdf2 package and encode with b64. """
cryptedPassword = hashlib.pbkdf2_hmac(
CryptUtility.PBKDF2_ENCRYPTION,
password, salt,
CryptUtility.PBKDF2_ITERATIONS,
CryptUtility.PBKDF2_KEY_LENGTH_IN_BYTES)
encodedPassword = base64.b64encode(cryptedPassword)
return '%s%s%s' % (salt, CryptUtility.SALT_DELIMITER, encodedPassword)
@classmethod
def verifyPasswordWithPbkdf2(cls, password, cryptedPassword):
""" Verify crypted password. """
# Get salt
salt = '%s' % cryptedPassword.split(CryptUtility.SALT_DELIMITER)[0]
# Verify crypted password
return cryptedPassword == cls.saltAndCryptPasswordWithPbkdf2(password, salt)
#######################################################################
# Testing.
if __name__ == '__main__':
import sys
#password = "dm"
password = sys.argv[1]
print 'Clear text: ', password
#cryptedPassword = CryptUtility.cryptPassword(password)
#print 'Crypted: ', cryptedPassword
#isVerified = CryptUtility.verifyPassword(password, cryptedPassword)
#print 'Verify: ', isVerified
cryptedPassword = CryptUtility.cryptPasswordWithPbkdf2(password)
print 'Crypted: ', cryptedPassword
isVerified = CryptUtility.verifyPasswordWithPbkdf2(password, cryptedPassword)
print 'Verify: ', isVerified