1

古い DBMS_OBFUSCATION_TOOLKIT パッケージを使用して PL/SQL + Oracle で暗号化を行う必要がありますが、Java と Javascript の両方で復号化できる必要があります (それが単語でさえある場合)。Java および JS 復号化は、PKCS#7 / PCKS#5 パディングに使用します。ゼロ パディングを実装するのは簡単です (と思います)。Java と JS を変更することもできますが、ゼロ パディングが元に戻せないという問題が発生するかどうかはわかりません。

したがって、独自の PKCS#7 を作成したいと考えていますが、適切な出力を生成するのに問題があります。このコードは、私が持っているものと、PKCS#5 が実装されている DBMS_CRYPTO からの出力のサイズを比較していますが、権限の問題により、すべての従業員が利用できるわけではありません。

  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

ご覧のとおり、パディングは正しく適用されているように見えますが (After padding RAW の末尾に 0202 が存在)、DBMS_CRYPTO は DBMS_OBFUSCATION_TOOLKIT とは異なる結果を生成しています。理由はありますか?

前もって感謝します!

4

2 に答える 2

0

" PKCS#5 が実装されている DBMS_CRYPTO からの出力ですが、権限の問題により、すべての従業員が利用できるわけではありません:"

他の従業員は DBMS_CRYPTO にアクセスする必要はありません。関数にアクセスする必要があるだけです。したがって、制限された機能を特定の承認された方法で使用する関数を構築し、より広範な権限の問題に違反することなく、広く利用できるようにすることができます。

もちろん、私はあなたのアプリケーションが賢明な方法でスキーマを実装していると仮定しています。これにより、オブジェクトに対する必要最小限の権限を分散できます。詳細を知りたい場合は、ごく最近、同様の問題に関するブログ記事を書きました。

于 2013-07-26T09:30:52.490 に答える
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-key 3des であるため、which => 13key に変更する必要がありました。助けてくれてありがとう!

編集: PKCS#7/5 仕様の誤解により、元の「ソリューション」は長さ %8 == 0 の文字列で実際に失敗しました... 上記のソリューションを更新して、コード全体/機能を表示しました。

于 2013-07-29T06:45:11.277 に答える