Code to generate user password hash in Oracle 10G with C#?

Asked

Viewed 474 times

4

I need to authenticate users in a web application in the Oracle 10g database, but the credentials are native to the database by running an Oracle Forms application already, and we would like to keep the same password on both systems (Single Sign-On).

For this I need to encrypt via C#, the password that the user enters in the WEB form to be able to authenticate (validation if the generated HASH is equal to saved in the database!).

I found this code in PHP, but even tried to convert more without success, since PHP is not my strong:

<?php
function oracle($un, $pw)
{
    $pt  = strtoupper($un . $pw);
    $pt .= str_repeat("\0", 3 - ((strlen($pt) - 1) & 3));
    $end = strlen($pt);
    $pt .= $pt;
    for ($a = 0; $a < $end; $a++)
    {
        $pt[2 * $a] = "\0";
        $pt[2 * $a + 1] = $pt[$a + $end];
    }
    $ct = mcrypt_encrypt(MCRYPT_DES, hex2bin('0123456789ABCDEF'), $pt, 'cbc', "\0\0\0\0\0\0\0\0");
    $ct = mcrypt_encrypt(MCRYPT_DES, substr($ct, -8), $pt, 'cbc', "\0\0\0\0\0\0\0\0");
    return bin2hex(substr($ct, -8));
}
?>

And it really works because I tested with the following data:

User: route

Password: test

Generated Hash: 89574FB579B04A40 (same as in the database)

If anyone can help me, I’d appreciate it!

  • Your question, is about PHP or C#?

  • "For this I need to encrypt via C#" .... I have a PHP code that does what I need ... but I would need it in C# !

  • 1

    The correct way to integrate an Oracle SSO layer and an application . NET is by using the native Application Server service (10gAS or higher). Doubling of hashes will undermine the security of both systems.

  • @Onosendai we will not duplicate Hashes, only use to authenticate the HASH already generated by Oracle... only to authenticate via WEB! Nothing more... If you change the password by the database system, the HASH to be authenticated by the web will be the new one generated by the oracle system! I appreciate your suggestion... but I could not see the fragilization in both systems doing so, could be more explicit ?

  • @Mauritius Assume a malicious agent who does not know the algorithm used to generate the hash. Your application is a C# client that runs locally. Owned by Assembly, this agent decompiles your program (using a tool like Dotpeek.) He now knows the generation algorithm of hash; Not only has your client program been compromised, but also the remote service.

  • @Onosendai understood friend... Thanks for the remark...

Show 1 more comment

1 answer

1

Follow the PHP code converted to C#.

    public static string HashOracle(string usuario, string senha)
    {
        senha = (usuario + senha).ToUpper();
        senha = senha + "".PadLeft(3 - ((senha.Length - 1) & 3), '\0');
        var len = senha.Length;
        var array = (senha + senha).ToCharArray();
        for (int i = 0; i < len; i++)
        {
            array[i * 2] = '\0';
            array[i * 2 + 1] = array[i + len];
        }

        senha = new string(array);
        string hash = Crypt(senha, "0123456789ABCDEF", "0000000000000000");
        hash = Crypt(senha, hash.Substring(hash.Length - 16), "0000000000000000");
        hash = hash.Substring(hash.Length - 16);
        return hash.ToUpper();
    }

    public static string Crypt(string text, string hexKey, string hexIV)
    {
        byte[] key = Hex2bin(hexKey);
        byte[] iv = Hex2bin(hexIV);
        System.Security.Cryptography.DES algorithm = System.Security.Cryptography.DES.Create();
        algorithm.Mode = System.Security.Cryptography.CipherMode.CBC;
        algorithm.Padding = System.Security.Cryptography.PaddingMode.None;
        System.Security.Cryptography.ICryptoTransform transform = algorithm.CreateEncryptor(key, iv);
        byte[] inputbuffer = Encoding.UTF8.GetBytes(text);
        byte[] outputBuffer = transform.TransformFinalBlock(inputbuffer, 0, inputbuffer.Length);
        return Bin2hex(outputBuffer);
    }

    public static byte[] Hex2bin(string hex)
    {
        return Enumerable.Range(0, hex.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                         .ToArray();
    }

    public static string Bin2hex(byte[] ba)
    {
        StringBuilder hex = new StringBuilder(ba.Length * 2);
        foreach (byte b in ba)
            hex.AppendFormat("{0:x2}", b);
        return hex.ToString();
    }

Remarks:

I used the UTF8 encoding but it may be necessary to check which encoding Oracle uses in passwords (accented passwords may be a problem. In the code I previously sent to you, I used ASCII).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.