2013-07-26 34 views
1

我需要在PL/SQL + Oracle中使用过时的DBMS_OBFUSCATION_TOOLKIT包进行一些加密,但它必须在Java和Javascript中可解密(如果这甚至是单词) 。 Java和JS解密用于PKCS#7/PCKS#5填充。这很简单(我认为)实现零填充,我可以改变Java和JS,但我不知道我是否会遇到零填充不可逆的问题。在PL/SQL中滚动我自己的PKCS#7填充

因此,我想推出自己的PKCS#7,但在生成正确的输出时遇到了一些麻烦。此代码进行比较我与来自DBMS_CRYPTO输出,其中有PKCS#5实现规模有副作用,但并不适用于所有员工,由于权限问题:

FUNCTION DESWithPKCS5Padding(trash VARCHAR2) 
    RETURN VARCHAR2 
    IS 
    lv_encrypted_data   VARCHAR2 (2000); 
    lv_decrypted_data   VARCHAR2 (2000); 
    piv_str      VARCHAR2 (2000) := 'apples'; 
    piv_pass_key    VARCHAR2 (2000) := 'testForNathan123testForN'; 
    a_var      VARCHAR2 (100); 
    num_padding_bytes    Int; 
    padding_bytes    raw(100); 
    test_byte     raw(1); 
    zero_byte     raw(1); 
    piv_raw      raw(2000); 
    piv_raw_orig    raw(2000); 
    error_in_input_buffer_length EXCEPTION; 
    PRAGMA EXCEPTION_INIT (error_in_input_buffer_length, -28232); 
    input_buffer_length_err_msg VARCHAR2 (100) := 
    BEGIN 
     dbms_output.Put_line ('Input_string->:' 
          || piv_str); 

    -- Since 3DES needs data to be in multiples of 8 bytes we had pad the data, if the 
    -- data did not meet the 8 bytes boundary requirement. 
    num_padding_bytes := MOD(Length(piv_str),8); 

    piv_raw_orig := utl_raw.cast_to_raw(piv_str); 

    IF (num_padding_bytes) != 0 THEN 
    padding_bytes := ''; 
    zero_byte := '0'; 
    test_byte := utl_raw.cast_to_raw(8-num_padding_bytes); 
    test_byte := utl_raw.bit_and(test_byte, '0F'); 

    for lcntr in 1..8-num_padding_bytes 
     loop 
     padding_bytes := UTL_RAW.CONCAT(padding_bytes, test_byte); 
     end loop; 

     piv_raw := utl_raw.concat(utl_raw.cast_to_raw(piv_str), padding_bytes); 
    END IF; 

    dbms_output.put_line('Without padding: ' || piv_raw_orig); 
    dbms_output.put_line('After padding: '|| piv_raw); 

    lv_encrypted_data := dbms_obfuscation_toolkit.Des3encrypt ( 
         input => piv_raw, key => utl_raw.cast_to_raw(piv_pass_key), 
         which => 1); 

    dbms_output.Put_line ('Encrypted Data OBFS: ' 
         || lv_encrypted_data); 

    lv_encrypted_data := dbms_crypto.encrypt (src => piv_raw_orig, 
     KEY => utl_raw.cast_to_raw(piv_pass_key), typ => dbms_crypto.des3_cbc_pkcs5); 

    dbms_output.Put_line ('Encrypted Data CRYPTO: ' 
         || (lv_encrypted_data));        

    lv_decrypted_data := dbms_crypto.Decrypt (src => lv_encrypted_data, 
     KEY => utl_raw.cast_to_raw(piv_pass_key), typ => dbms_crypto.des3_cbc_pkcs5); 

    dbms_output.Put_line('Decrypted: ' || utl_raw.cast_to_varchar2(lv_decrypted_data)); 
END; 

和输出:

Input_string->:apples 
Without padding: 6170706C6573 
After padding: 6170706C65730202 
Encrypted Data OBFS: 36DEFCBBC60BC58A 
Encrypted Data CRYPTO: CF7676DF282DCC5C 
Decrypted: apples 

正如您所看到的,它看起来正在正在应用填充(0202存在于After填充RAW后),但DBMS_CRYPTO产生的结果与DBMS_OBFUSCATION_TOOLKIT不同。任何想法为什么?

在此先感谢!

回答

0
function ApplyPKCS5Padding (v_to_pad raw) 
    return raw 
    IS 
    a_var      VARCHAR2 (100); 
    num_padding_bytes    Int; 
    padding_bytes    raw(100); 
    test_byte     raw(1); 
    zero_byte     raw(1); 
    output      raw(2000); 
    BEGIN       
     -- Since DES needs data to be in multples of 8 bytes we pad the data, if the 
     -- data did not meet the 8 bytes boundry requirment. 
     num_padding_bytes := MOD(Length(utl_raw.cast_to_varchar2(v_to_pad)),8); 
     output := v_to_pad; 

     IF (num_padding_bytes) != 0 THEN 
     padding_bytes := ''; 
     zero_byte := '0'; 

     test_byte := utl_raw.cast_to_raw(8-num_padding_bytes); 
     test_byte := utl_raw.bit_and(test_byte, '0F'); 

     for lcntr in 1..8-num_padding_bytes 
      loop 
      padding_bytes := UTL_RAW.CONCAT(padding_bytes, test_byte); 
      end loop; 

      output := utl_raw.concat(v_to_pad, padding_bytes); 
     ELSE 
     padding_bytes := '0808080808080808'; 
     output := utl_raw.concat(v_to_pad, padding_bytes); 
     END IF; 

    return output; 

    END; 

默认IV是...我不知道,但OBFS工具包和DBMS_CRYPTO有一个不同的。我只需要指定它,我用0 IV做了测试。此外,OBFS的默认值是2键3des,所以我需要which => 1将其更改为3key。谢谢您的帮助!

编辑: 由于PKCS#7/5规范的误解,原始“解决方案”实际上在长度为%8 == 0的字符串上失败......我更新了上面的解决方案以显示整个/功能代码。

0

“从DBMS_CRYPTO输出,其中有PKCS#5来实现,但 并不适用于所有员工,由于权限问题:”

其他员工并不需要访问DBMS_CRYPTO ,他们只需要访问您的功能。因此,您可以构建一个功能,以特定和批准的方式使用受限功能,并在不违反更广泛的权限问题的情况下将其广泛使用。

当然,我假设你的应用程序已经以合理的方式实现了模式,它允许分散对象的最小必需特权。如果您想find out more,我最近写了一篇关于类似问题的博客文章。

+0

你可能是正确的,但不幸的是,根据我的老板,这是“唯一的选择”:/ – PunDefeated