passlib.hash.oracle10 - Oracle 10g password hash¶
Danger
This algorithm is dangerously insecure by modern standards. It is trivially broken, and should not be used if at all possible. For new code, see the list of recommended hashes.
This class implements the hash algorithm used by the Oracle Database up to version 10g Rel.2. It was superseded by a newer algorithm in Oracle 11. This class can be used directly as follows (note that this class requires a username for all encrypt/verify operations):
from passlib.hash import oracle10 as oracle10
# hash password using specified username
hashed = oracle10.hash("password", user="username")
print(hashed)
# > '872805F3F4C83365'
# verify correct password
print(oracle10.verify("password", hashed, user="username"))
# > True
# verify correct password w/ wrong username
print(oracle10.verify("password", hashed, user="somebody"))
# > False
# verify incorrect password
print(oracle10.verify("letmein", hashed, user="username"))
# > False
Tip
See also: the generic PasswordHash usage examples
Warning
This implementation has not been compared very carefully against the official implementation or reference documentation, and its behavior may not match under various border cases. caveat emptor.
Interface¶
oracle10
¶
oracle10(user=None, **kwds)
This class implements the password hash used by Oracle up to version 10g, and follows the :ref:password-hash-api.
It does a single round of hashing, and relies on the username as the salt.
The :meth:~passlib.ifc.PasswordHash.hash, :meth:~passlib.ifc.PasswordHash.genhash, and :meth:~passlib.ifc.PasswordHash.verify methods all require the
following additional contextual keywords:
Parameters:
-
user(str, default:None) –name of oracle user account this password is associated with.
encrypt
classmethod
¶
encrypt(*args, **kwds)
Legacy alias for :meth:hash.
.. deprecated:: 1.7
This method was renamed to :meth:!hash in version 1.7.
This alias will be removed in version 2.0, and should only
be used for compatibility with Passlib 1.3 - 1.6.
parsehash
classmethod
¶
parsehash(hash, checksum=True, sanitize=False)
[experimental method] parse hash into dictionary of settings.
this essentially acts as the inverse of :meth:hash: for most
cases, if hash = cls.hash(secret, **opts), then
cls.parsehash(hash) will return a dict matching the original options
(with the extra keyword checksum).
this method may not work correctly for all hashes, and may not be available on some few. its interface may change in future releases, if it's kept around at all.
Parameters:
-
hash–hash to parse
-
checksum–include checksum keyword? (defaults to True)
-
sanitize–mask data for sensitive fields? (defaults to False)
Format & Algorithm¶
Oracle10 hashes all consist of a series of 16 hexadecimal digits, representing the resulting checksum. Oracle10 hashes can be formed by the following procedure:
- Concatenate the username and password together.
- Convert the result to upper case
- Encoding the result in a multi-byte format 1 such that ascii characters (eg:
USER) are represented with additional null bytes inserted (eg:\x00U\x00S\x00E\x00R). - Right-pad the result with null bytes, to bring the total size to an integer multiple of 8. this is the final input string.
- The input string is then encoded using DES in CBC mode.
The string
\x01\x23\x45\x67\x89\xAB\xCD\xEFis used as the DES key, and a block of null bytes is used as the CBC initialization vector. All but the last block of ciphertext is discarded. - The input string is then run through DES-CBC a second time; this time the last block of ciphertext from step 5 is used as the DES key, a block of null bytes is still used as the CBC initialization vector. All but the last block of ciphertext is discarded.
- The last block of ciphertext of step 6 is converted to a hexadecimal string, and returned as the checksum.
Security Issues¶
This algorithm it not suitable for any use besides manipulating existing Oracle10 account passwords, due to the following flaws 2:
-
Its use of the username as a salt value means that common usernames (e.g.
system) will occur more frequently as salts, weakening the effectiveness of the salt in foiling pre-computed tables. -
The fact that it is case insensitive, and simply concatenates the username and password, greatly reduces the keyspace that must be searched by brute-force or pre-computed attacks.
-
Its simplicity, and decades of research on high-speed DES implementations, makes efficient brute force attacks much more feasible.
Deviations¶
Passlib's implementation of the Oracle10g hash may deviate from the official implementation in unknown ways, as there is no official documentation. There is only one known issue:
- Unicode Policy
Lack of testing (and test vectors) leaves it unclear
as to how Oracle 10g handles passwords containing non-7bit ascii.
In order to provide support for unicode strings,
Passlib will encode unicode passwords using utf-16-be 1
before running them through the Oracle10g algorithm.
This behavior may be altered in the future, if further testing
reveals another behavior is more in line with the official representation.
This note applies as well to any provided username,
as they are run through the same policy.
References¶
- Description of Oracle10g and Oracle11g algorithms - http://www.notesbit.com/index.php/scripts-oracle/oracle-11g-new-password-algorithm-is-revealed-by-seclistsorg/.
-
The exact encoding used in step 3 of the algorithm is not clear from known references. Passlib uses
utf-16-be, as this is both compatible with existing test vectors, and supports unicode input. ↩↩ -
Whitepaper analyzing flaws in this algorithm - http://www.isg.rhul.ac.uk/~ccid/publications/oracle_passwd.pdf. ↩