【问题标题】:Oracle dbms_crypto for PKCS7用于 PKCS7 的 Oracle dbms_crypto
【发布时间】:2020-05-22 18:54:52
【问题描述】:

我的要求是执行 dbms_crypto 工具来解密从 DOTNET 端加密的表中的加密列。 看起来PKCS7方法用于dotnet,我无法在Oracle端找到相应的填充; PKCS5 可用。

如果可以从 plsql 方面获得所需的值,任何人都可以帮助我:

Dot Net 加密代码如下:

private static void Encrypt()
{
    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes("ID:5031743749436704");
    byte[] keyArray = new byte[16] {
     34,
     170,
     219,
     38,
     68,
     125,
     135,
     181,
     80,
     177,
     85,
     164,
     215,
     100,
     250,
     208 };
    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    //set the secret key for the tripleDES algorithm
    tdes.Key = keyArray;
    //mode of operation. there are other 4 modes.
    //We choose ECB(Electronic code Book)
    tdes.Mode = CipherMode.CBC;
    //padding mode(if any extra byte added)
    tdes.IV = new byte[8];
    tdes.Padding = PaddingMode.PKCS7;
    ICryptoTransform cTransform = tdes.CreateEncryptor();
    //transform the specified region of bytes array to resultArray
    byte[] resultArray =
      cTransform.TransformFinalBlock(toEncryptArray, 0,
      toEncryptArray.Length);
    //Release resources held by TripleDes Encryptor
    tdes.Clear();
    //Return the encrypted data into unreadable string format
    string enCryptedString = Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

private static void Decrypt()
{
    byte[] toEncryptArray = Convert.FromBase64String("T71mQdBbEwnk5kZKAc+16kgsrln4EkCJ");

    byte[] keyArray = new byte[16] {
     34,
     170,
     219,
     38,
     68,
     125,
     135,
     181,
     80,
     177,
     85,
     164,
     215,
     100,
     250,
     208 };
    //string s = Convert.ToBase64String(keyArray);

    //string s1 = UTF8Encoding.UTF8.GetString(keyArray);

    //string s3 = UTF32Encoding.UTF32.GetString(keyArray);

    //string s4 = UTF7Encoding.UTF7.GetString(keyArray);


    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    //set the secret key for the tripleDES algorithm
    tdes.Key = keyArray;
    //mode of operation. there are other 4 modes. 
    //We choose ECB(Electronic code Book)

    tdes.Mode = CipherMode.CBC;
    //padding mode(if any extra byte added)
    //tdes.Padding = PaddingMode.PKCS7;

    tdes.IV = new byte[8];

    ICryptoTransform cTransform = tdes.CreateDecryptor();

    byte[] resultArray = cTransform.TransformFinalBlock(
                         toEncryptArray, 0, toEncryptArray.Length);
    //Release resources held by TripleDes Encryptor                
    tdes.Clear();



    //return the Clear decrypted TEXT
    string decryptedString = UTF8Encoding.UTF8.GetString(resultArray);

    string s2 = Convert.ToBase64String(resultArray); // Base 64 string of raw cc token


    var str = System.Text.Encoding.Default.GetString(new byte[8]);

}

Oracle 尝试如下:

--encrypt
SET SERVEROUTPUT ON;
DECLARE
     l_encrypted   RAW(128);
BEGIN
     l_encrypted := dbms_crypto.encrypt(src => utl_raw.cast_to_raw('ID:5031743749436704'), 
                                        typ => dbms_crypto.des3_cbc_pkcs5, 
                                        key => utl_encode.base64_decode(utl_raw.cast_to_raw('IqrbJkR9h7VQsVWk12T60A==') ) 
                                        );

     dbms_output.put_line( UTL_I18N.RAW_TO_CHAR(utl_encode.base64_encode(l_encrypted),'AL32UTF8'));
END;
/
/*
actual result:      VOsHqOuCJUSVYMta4Bz2tSe/aMDN+Ol9
expected result:    oCQBWzcu9gCYmxf0kL3oTgkX/K8UVk/t
*/


--decrypt
SET SERVEROUTPUT ON;
DECLARE
     l_decrypted RAW(128);
BEGIN
      l_decrypted := dbms_crypto.decrypt(src => utl_encode.base64_decode(utl_raw.cast_to_RAW('oCQBWzcu9gCYmxf0kL3oTgkX/K8UVk/t')),
                                        typ => DBMS_CRYPTO.des3_cbc_pkcs5,
                                        key => utl_encode.base64_decode(utl_raw.cast_to_raw('IqrbJkR9h7VQsVWk12T60A==') )
                                        );
      dbms_output.put_line( UTL_I18N.RAW_TO_CHAR(l_decrypted,'AL32UTF8'));
END;
/

/*
actual result: 

Error report -
ORA-28817: PL/SQL function returned an error.
ORA-06512: at "SYS.DBMS_CRYPTO_FFI", line 67
ORA-06512: at "SYS.DBMS_CRYPTO", line 44
ORA-06512: at line 4
28817. 00000 -  "PL/SQL function returned an error."
*Cause:    A PL/SQL function returned an error unexpectedly.
*Action:   This is an internal error. Enable tracing to find more
           information. Contact Oracle customer support if needed.
*Document: NO

expected result: ID:5031743749436704
*/

【问题讨论】:

    标签: .net oracle plsql oracle11g dbms-crypto


    【解决方案1】:

    正如 Mark 所说,dbms_crypto 目前不支持 PKCS7。

    要回答您的问题,即为什么您的 PKCS5 代码失败并出现(诚然无用)错误“PL/SQL 函数意外返回错误。”,您的问题是您调用的函数来转换值srckey 参数不太正确。您无需调用utl_encode.base64_decode 即可转换原始键值。此外,您传递给src 的值应该与您从原始加密原始数据转换为字符串的方式相反 - 即显示加密值,您调用utl_encode.base64_encode 后跟utl_i18n.raw_to_char。要将生成的字符串转换回原始字符串,您需要执行完全相反的操作 - 即调用 utl_i18n.string_to_raw,然后调用 utl_encode.base64_decode

    这是一个工作示例:

    SET SERVEROUTPUT ON;
    DECLARE
         l_encrypted   RAW(128);
         l_decrypted   RAW(128);
         l_key         RAW(128);
    BEGIN
         l_key := utl_raw.cast_to_raw('IqrbJkR9h7VQsVWk12T60A==');
    
         l_encrypted := dbms_crypto.encrypt(src => utl_raw.cast_to_raw('ID:5031743749436704'), 
                                            typ => dbms_crypto.des3_cbc_pkcs5, 
                                            key => l_key
                                            );
    
         dbms_output.put_line(
           UTL_I18N.RAW_TO_CHAR(
             utl_encode.base64_encode(l_encrypted),'AL32UTF8'));
    
         l_encrypted := utl_encode.base64_decode(
           utl_i18n.string_to_raw('tKQyG9kMqEMyv28q/dDXfGuWbf+Dnday','AL32UTF8'));
    
         dbms_output.put_line(
           UTL_I18N.RAW_TO_CHAR(
             utl_encode.base64_encode(l_encrypted),'AL32UTF8'));
    
         l_decrypted := dbms_crypto.decrypt(src => l_encrypted,
                                            typ => DBMS_CRYPTO.des3_cbc_pkcs5,
                                            key => l_key
                                            );
    
         dbms_output.put_line( UTL_I18N.RAW_TO_CHAR(l_decrypted,'AL32UTF8'));
    END;
    /
    
    tKQyG9kMqEMyv28q/dDXfGuWbf+Dnday
    tKQyG9kMqEMyv28q/dDXfGuWbf+Dnday
    ID:5031743749436704
    

    LiveSQL

    【讨论】:

    • 感谢 Jeffrey 的帮助,但不幸的是,该解决方案无法满足我的要求。所以我们计划从客户端本身进行这项活动。
    • 当然不会 - 很明显您需要 PKCS7 的解决方案。我只是在回答你的问题。
    【解决方案2】:

    Oracle 的 DBMS_CRYPTO 包不支持 PKCS7。

    Here 是您的选择。

    【讨论】:

    • 谢谢,我什至尝试过使用它,这将完成源数据的填充/修剪;但是我将如何为“typ”提供参数?以及如何在解密时解决错误?该帖子没有提供太多详细信息。
    • @ajmalmhd04,typ 参数只是告诉dbms_crypto 使用什么类型的加密。由于建议的选项不涉及使用dbms_crypto,并且仅支持一种加密类型(PKCS7),因此无需指定类型。
    • 感谢 Mark 和 @Jeffrey 的解释。
    猜你喜欢
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    相关资源
    最近更新 更多