We have a database table which contains passwords hashed with SHA512. When a user logs into the system it compares their hashed entered password with a hashed password stored in a table. I am trying to create a user through a PL/SQL script and I need to replicate the same process as the system does to create the user when it does it through the front end.
I'm having trouble clarifying if the salt I am generating for the hash in Oracle is what is generated by the system in C#. Since when I try to login and debug the system code, the hashed password generated by the system is not matching what I created through my PL/SQL script.
Currently, the system generates the hash with:
public string GetSalt(int count) // count = 32
{
byte [] salt = new byte[count];
using (var gen = new RNGCyptoServiceProvider()) // System.Security.Cryptography
{
gen.GetBytes(salt);
}
return Convert.ToBase64String(salt);
}
So we should get a cryptographically strong sequence of random values based on the docs for GetBytes()
.
What I am doing in Oracle is the following:
FUNCTION GetSalt RETURN SomePasswordTable.Salt%TYPE IS
defaultSaltLength VARCHAR2(4);
randomBytes RAW(1024);
BEGIN
BEGIN
SELECT SaltLength
INTO defaultSaltLength -- This will be '32'
FROM SomeTable
WHERE someValue = 1
AND someOtherValue = 'SALTLN';
EXCEPTION
WHEN OTHERS THEN
defaultSaltLength := '32';
END;
randomBytes := DBMS_CRYPTO.RandomBytes(TO_NUMBER(defaultSaltLength));
RETURN utl_raw.cast_to_varchar2(utl_encode.base64_encode(randomBytes));
END;
My question is, am I doing the same in Oracle as the system is doing in C#?
Based on the Oracle DBMS_CRYPTO
docs, RandomBytes()
should also return me a cryptographically secure pseudo-random sequence of bytes.
Since both methods use the same hashing function. DBMS_CRYPTO.HASH_SH512
in Oracle and PBKDF2HashAlgorithm.SHA512
in C#, this is the only place I can think of where the hashing is going wrong on the Oracle side.
Is what I am doing correct? Why am I getting a different hash?