Дополнительные функции шифрования и дешифрования между Oracle и .Net

Я ищу код, который шифрует строку в Oracle PL/SQL, используя DBMS_CRYPTO и соответствующий код дешифрования в .Net framework. Оба должны будут использовать один и тот же ключ, IV и режим заполнения (где это необходимо). Я не очень разбираюсь в алгоритмах криптографии, но если кто-то может предоставить точный код для обеих сторон, я был бы очень признателен... спасибо!

Мой коллега использует следующий код для шифрования текста "Test1234", результат которого: 54AA98D8DE586F346E54B179AB71C6D7

G_CHARACTER_SET VARCHAR2(10) := 'AL32UTF8';

G_STRING VARCHAR2(32) := '12345678901234567890123456789012';

G_KEY RAW(250) := utl_i18n.string_to_raw
                  ( data => G_STRING,
                    dst_charset => G_CHARACTER_SET );

G_ENCRYPTION_TYPE PLS_INTEGER := dbms_crypto.pad_zero
                                + dbms_crypto.encrypt_aes256 
                                + dbms_crypto.chain_cbc;


FUNCTION encryptSSN( p_ssn IN VARCHAR2 ) RETURN RAW
IS

l_ssn RAW(32) := UTL_I18N.STRING_TO_RAW( p_ssn, G_CHARACTER_SET );

l_encrypted RAW(32);

BEGIN

l_encrypted := dbms_crypto.encrypt
               ( src => l_ssn,
                 typ => G_ENCRYPTION_TYPE,
                 key => G_KEY );

RETURN l_encrypted;

END encrypt_ssn;

В моем коде .Net я попробовал это как дополнительную функцию для шифрования таким же образом, но это дает мне совершенно другой результат!

public static string EncryptAES(string text)
    {
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.Key = Encoding.UTF8.GetBytes("12345678901234567890123456789012");
        aes.IV = Encoding.UTF8.GetBytes("0123456789ABCDEF"); // Oracle's Default IV
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.Zeros;

        // Convert string to byte array
        byte[] src = Encoding.UTF8.GetBytes(text);

        // encryption
        using (ICryptoTransform encrypt = aes.CreateEncryptor())
        {
            byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);

            // Convert byte array to Base64 strings
            return Convert.ToBase64String(dest);
        }
    }

person ZiggY    schedule 01.06.2020    source источник
comment
Можете ли вы предоставить код для того, что вы пробовали до сих пор?   -  person jasttim    schedule 01.06.2020
comment
Привет, @jasttim... я добавил для тебя код выше. Я уверен, что что-то не так в подходе. Не стесняйтесь дать мне совершенно другое решение, если оно у вас есть. Мы просто хотим иметь возможность зашифровать строку в Oracle и расшифровать ее в .Net, подойдет любой безопасный алгоритм.   -  person ZiggY    schedule 01.06.2020
comment
@jasttim есть идеи?   -  person ZiggY    schedule 02.06.2020
comment
Привет, у меня не было времени просматривать ваши последние обновления, вы можете обратиться к другим, хотя они должны быть в состоянии помочь вам   -  person jasttim    schedule 02.06.2020


Ответы (1)


Значение IV Oracle по умолчанию равно NULL в соответствии с: docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_crypto.htm#i1002112

.NET не допустит NULL IV, поэтому измените режим на ECB.

Изменение вашего кода на приведенный ниже возвращает значение, ожидаемое в соответствии с вашим вопросом:

public static string EncryptAES(string text)
        {
            AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
            aes.Key = Encoding.UTF8.GetBytes("12345678901234567890123456789012");
            //aes.IV = Encoding.UTF8.GetBytes("0123456789ABCDEF"); - Remove
            aes.Mode = CipherMode.ECB; // Change mode to ECB
            aes.Padding = PaddingMode.Zeros;

            // Convert string to byte array
            byte[] src = Encoding.UTF8.GetBytes(text);

            // encryption
            using (ICryptoTransform encrypt = aes.CreateEncryptor())
            {
                byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);

                StringBuilder hex = new StringBuilder(dest.Length * 2);
                foreach (byte b in dest)
                    hex.AppendFormat("{0:x2}", b);
                Console.WriteLine(hex);

                return hex.ToString() ;
            }
        }
person TestBench    schedule 03.06.2020
comment
Спасибо, это сработало! Однако только с входным текстом 16 символов и ниже, после этого шифрование вывода обоих отличается, есть ли способ это исправить? А также, если вы не возражаете, можете ли вы предоставить функцию расшифровки .Net? - person ZiggY; 03.06.2020
comment
@TestBunch какие-нибудь отзывы, пожалуйста...? - person ZiggY; 10.06.2020