2013-07-26 65 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