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
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