I have a web application based on Java/Spring that uses Oracle 11g. Currently, the users authenticate via username/password directly against the system table SYS.USER$ on login.
This has to change, so we created a (regular) new table to store all the user data there. We inserted all existing passwords to the newly created table. However, the passwords seem to be encrypted/hashed in a way that’s described by this site
One example: Once the user enters XXXXX, the database stores 07E4898C06DEF253.
I want to perform the authentication with the old passwords stored in the new (regular) table. My problem is that I don’t know how to verify the existing passwords since I don’t know exactly how they have been hashed/encrypted.
I played around with ora_hash and dbms_obfuscation_toolkit.DESDecrypt, but none of these gave me a correct result. I know the correct password for my user and I can see Oracle’s generated value for this one, but I can’t reproduce the way Oracle generally “handles” the password data.
Is there any way to solve this problem without resetting all passwords?
Adapting the Java implementation you linked to in a comment, which is close but isn’t quite using the salt properly:
Which gives output:
The PL/SQL version involves some conversion;
dbms_crypto.hash()takes aRAWargument, so you have to convert the plain-text password toRAW, then concatenate the extracted salt – which is already hex. (In the PL/SQL version in Pete Finnigan’s blog you may notice that he has an explicithextorawcall, so I’m simplifying a bit). So the argument passed todbms_crypto.hashfor your example would be the hex (OK, raw) equivalent ofZK3002, which is5A4B33303032, with the hex salt concatenated to that; so5A4B333030321DB70EE23BFB23BDFD48.For the Java version you pass a byte array, but that means you need to convert the salt extracted from the stored password back from hex before tacking it on to the password; and since it’s unlikely to have a useful string representation you might as well put it straight into a byte array. So, convert the password to a byte array, convert the salt into a byte array, and stick the two arrays together. That then becomes the value you pass to
MessageDigest.You can compare the hash this produces with the Oracle-hashed version, skipping the initial
S:and the embedded salt.