migration from .net to oracle 11g

79 views Asked by At

I need to migrate the following 3des encription process from .net to oracle 11g

    using System;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
                    
public class Program
{
    private const string strKey = "H9p-S5m2Dh6Fe7Ls3-Qs1D2e4Z";
    public static void Main()
    {
        var strToEncrypt = "test";
        TripleDESCryptoServiceProvider objDESCrypto = new TripleDESCryptoServiceProvider();
        MD5CryptoServiceProvider objHashMD5 = new MD5CryptoServiceProvider();
        byte[] byteHash, byteBuff;
        byteHash = objHashMD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(strKey));
        Console.WriteLine("v_key net = "+BitConverter.ToString(byteHash).Replace("-",""));
        objHashMD5 = null;
        objDESCrypto.Key = byteHash;
        objDESCrypto.Mode = CipherMode.CBC; //CBC, CFB
        objDESCrypto.Padding = PaddingMode.Zeros;
        Console.WriteLine("iv net = "+BitConverter.ToString(stringToHex("0123456789ABCDEF")).Replace("-",""));
        objDESCrypto.IV = stringToHex("0123456789ABCDEF");
        byteBuff = ASCIIEncoding.ASCII.GetBytes(strToEncrypt);
        Console.WriteLine("src net = "+BitConverter.ToString(byteBuff).Replace("-",""));
        var hashbyte = objDESCrypto.CreateEncryptor().TransformFinalBlock(byteBuff, 0, byteBuff.Length);
        Console.WriteLine("encrypted_str net = "+BitConverter.ToString(hashbyte).Replace("-",""));
        
        Console.WriteLine("encrypted_str64 net = " + Convert.ToBase64String(objDESCrypto.CreateEncryptor().
                    TransformFinalBlock(hashbyte, 0, hashbyte.Length)));
        var decrypted_str = ASCIIEncoding.ASCII.GetString
                (objDESCrypto.CreateDecryptor().TransformFinalBlock
                (hashbyte, 0, hashbyte.Length));
        Console.WriteLine("decrypted_str net = "+decrypted_str);
        string hexString = "43480170";
        
    }
    
    public static byte[] stringToHex(string hexString){
        //uint num = uint.Parse(hexString, System.Globalization.NumberStyles.AllowHexSpecifier);
        //byte[] floatVals = BitConverter.GetBytes(num);
        //return floatVals;
        return Enumerable.Range(0, hexString.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
                     .ToArray();
    }
}

available in https://dotnetfiddle.net/hGZZts whose output is

v_key net = 8B928C8346648BDDB14B627EFF4E66F1
iv net = 0123456789ABCDEF
src net = 74657374
encrypted_str net = F7BC988C0EA6EEE5
encrypted_str64 net = 73A6DqCayTc=
decrypted_str net = test

The oracle procedure i wrote is

    create or replace PACKAGE BODY Criptografia AS
    -- Clave de encriptación (asegúrate de que sea igual a la clave en C#)
    strKeyDataAD CONSTANT VARCHAR2(26) := 'H9p-S5m2Dh6Fe7Ls3-Qs1D2e4Z';
    
    PROCEDURE EncryptDataAD(strToEncrypt IN VARCHAR2) AS
        l_mod_ecb pls_integer;
        v_key raw(32);
        encrypted_str VARCHAR2(4000);
        encryptedBase64_str VARCHAR2(4000);
        decrypted_str VARCHAR2(4000);
    BEGIN
        l_mod_ecb := dbms_crypto.ENCRYPT_3DES+ dbms_crypto.CHAIN_CBC + DBMS_CRYPTO.PAD_ZERO ;
         dbms_output.put_line('l_mod_ecb oracle: '|| l_mod_ecb);
        v_key := dbms_crypto.hash(
            utl_i18n.string_to_raw(strKeyDataAD, 'AL32UTF8'),
            dbms_crypto.hash_md5
          );
        dbms_output.put_line('v_key oracle: '|| (v_key));
        --dbms_output.put_line('DEFAULT_IV oracle: '|| (dbms_crypto.LEGACY_DEFAULT_IV));--DBMS_CRYPTO.LEGACY_DEFAULT_IV
        dbms_output.put_line('src oracle: '|| utl_i18n.string_to_raw(strToEncrypt, 'AL32UTF8'));
        encrypted_str := dbms_crypto.encrypt(
                                  src => utl_i18n.string_to_raw(strToEncrypt, 'AL32UTF8'),
                                  typ => dbms_crypto.ENCRYPT_3DES + dbms_crypto.CHAIN_CBC + DBMS_CRYPTO.PAD_ZERO,
                                  --typ => dbms_crypto.DES3_CBC_PKCS5,
                                  key => dbms_crypto.hash(
                                        utl_i18n.string_to_raw(strKeyDataAD, 'AL32UTF8'),
                                        dbms_crypto.hash_md5
                                      )
                                  ,iv => hextoraw('0123456789ABCDEF')
                                  );
        dbms_output.put_line('encrypted_str oracle: '|| encrypted_str);
       
        dbms_output.put_line('encryptedBase64_str oracle: '|| utl_raw.cast_to_varchar2(utl_encode.base64_encode(encrypted_str)));
        decrypted_str := dbms_crypto.decrypt(
                                  src => encrypted_str,
                                  typ => dbms_crypto.ENCRYPT_3DES + dbms_crypto.CHAIN_CBC + DBMS_CRYPTO.PAD_ZERO,
                                  --typ => dbms_crypto.DES3_CBC_PKCS5,
                                  key => dbms_crypto.hash(
                                        utl_i18n.string_to_raw(strKeyDataAD, 'AL32UTF8'),
                                        dbms_crypto.hash_md5
                                      )
                                  ,iv => hextoraw ( '0123456789ABCDEF' )
                                  );
        
        dbms_output.put_line('decrypted_str oracle: '|| UTL_I18N.RAW_TO_CHAR(decrypted_str,'AL32UTF8'));

        --RETURN encrypted_str;
    END EncryptDataAD;
END Criptografia;

whose output is

l_mod_ecb oracle: 12545
v_key oracle: 8B928C8346648BDDB14B627EFF4E66F1
src oracle: 74657374
encrypted_str oracle: 28F7DA0F3B338BB1
encryptedBase64_str oracle: KPfaDzszi7E=
decrypted_str oracle: test

As you can see v_key (md5 hash in bytes) and src (input in bytes) are the same, but the output is different. i'tried changing the padding in oracle procedure (PAD_PKCS5, PAD_NONE and PAD_ZERO) and the chaining modifier (CHAIN_ECB,CHAIN_CBC,CHAIN_CFB y CHAIN_OFB) but i wasn't able to return the same result than my .net aplication. English isn't my native language so i apologize for any grammar error thank you in advance

1

There are 1 answers

1
Leandro Locani On

In the end the problem is that in both cases I am putting a 128-bit key but 3des requires a 192-bit key and .net to complete it repeating the first 8 bytes and Oracle does it in some other way. So the solution was to repeat the first 8 bytes in the oracle key so the result of 3des was the same in both sides