Generating md5 encrypted password for chpasswd

If you want to generate properly encrypted password to feed to chpasswd, the most easier and proper way is to do that from command line :

echo "encryptedpassword"|openssl passwd -1 -stdin

If you want to generate in pure python you can do it like that :

    def md5crypt(password, salt, magic='$1$'):
        import md5
        m = md5.new()
        m.update(password + magic + salt)

        # /* Then just as many characters of the MD5(pw,salt,pw) */
        mixin = md5.md5(password + salt + password).digest()
        for i in range(0, len(password)):
            m.update(mixin[i % 16])

        # /* Then something really weird... */
        # Also really broken, as far as I can tell.  -m
        i = len(password)
        while i:
            if i & 1:
                m.update('x00')
            else:
                m.update(password[0])
            i >>= 1

        final = m.digest()
        # /* and now, just to make sure things don't run too fast */
        for i in range(1000):
            m2 = md5.md5()
            if i & 1:
                m2.update(password)
            else:
                m2.update(final)
            if i % 3:
                m2.update(salt)
            if i % 7:
                m2.update(password)

            if i & 1:
                m2.update(final)
            else:
                m2.update(password)

            final = m2.digest()

        # This is the bit that uses to64() in the original code.
        itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
        rearranged = ''
        for a, b, c in ((0, 6, 12), (1, 7, 13), (2, 8, 14), (3, 9, 15), (4, 10, 5)):
            v = ord(final[a]) < < 16 | ord(final&#91;b&#93;) << 8 | ord(final&#91;c&#93;)
            for i in range(4):
                rearranged += itoa64&#91;v &amp; 0x3f&#93;; v >>= 6

        v = ord(final[11])
        for i in range(2):
            rearranged += itoa64[v &amp; 0x3f]; v >>= 6

        return magic + salt + '$' + rearranged

You need to feed it up with a salt, like this :

    def generate_salt(count):
        import random, string
        char = string.ascii_letters + string.digits + string.punctuation.replace(':', '')
        return string.join(map(lambda x,v=char: random.choice(v), range(count)), '')

3 thoughts on “Generating md5 encrypted password for chpasswd”

  1. -m is to encrypt the final passwd in MD5 instead of the very bad DES. You will not be able to furnish on the command line the encrypted MD5 but will have to pass the clear password.

Comments are closed.