windows_3.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536
  1. def raw(cls, secret, encoding=None):
  2. """encode password using LANMAN hash algorithm.
  3. :type secret: unicode or utf-8 encoded bytes
  4. :arg secret: secret to hash
  5. :type encoding: str
  6. :arg encoding:
  7. optional encoding to use for unicode inputs.
  8. this defaults to ``cp437``, which is the
  9. common case for most situations.
  10. :returns: returns string of raw bytes
  11. """
  12. if not encoding:
  13. encoding = cls.default_encoding
  14. # some nice empircal data re: different encodings is at...
  15. # http://www.openwall.com/lists/john-dev/2011/08/01/2
  16. # http://www.freerainbowtables.com/phpBB3/viewtopic.php?t=387&p=12163
  17. from passlib.crypto.des import des_encrypt_block
  18. MAGIC = cls._magic
  19. if isinstance(secret, unicode):
  20. # perform uppercasing while we're still unicode,
  21. # to give a better shot at getting non-ascii chars right.
  22. # (though some codepages do NOT upper-case the same as unicode).
  23. secret = secret.upper().encode(encoding)
  24. elif isinstance(secret, bytes):
  25. # FIXME: just trusting ascii upper will work?
  26. # and if not, how to do codepage specific case conversion?
  27. # we could decode first using <encoding>,
  28. # but *that* might not always be right.
  29. secret = secret.upper()
  30. else:
  31. raise TypeError("secret must be unicode or bytes")
  32. secret = right_pad_string(secret, 14)
  33. return des_encrypt_block(secret[0:7], MAGIC) + \
  34. des_encrypt_block(secret[7:14], MAGIC)