sql >> データベース >  >> RDS >> Oracle

DBMS_CRYPTO関数を使用してCLOBデータを復号化中にエラーが発生しました

    エラーは33行目から発生しています。これは次のとおりです。

    l_raw    := UTL_ENCODE.base64_decode(l_temp);
    

    base64_decode 機能 RAW引数が必要なため、現在の文字列を変換できます:

    l_raw    := UTL_ENCODE.base64_decode(UTL_RAW.cast_to_raw(l_temp));
    

    つまり

       FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(ac_input) - 1 )/l_amt) LOOP
          DBMS_LOB.read(ac_input, l_amt, l_offset, l_temp);
          l_offset := l_offset + l_amt;
          l_raw    := UTL_ENCODE.base64_decode(UTL_RAW.cast_to_raw(l_temp));
          DBMS_LOB.append (l_blob, TO_BLOB(l_raw));
        END LOOP; 
    

    base-64文字列には改行があります。それらはデコードを捨てています。 l_amt = 64のように、より小さなチャンクサイズを使用できます。 、改行をスキップします:

       FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(ac_input) - 1 )/(l_amt + 2)) LOOP
          DBMS_LOB.read(ac_input, l_amt, l_offset, l_temp);
          l_offset := l_offset + l_amt + 2;
    

    ただし、新しいl_clobを使用して、一度にすべてを削除する方がおそらく簡単で効率的です。 変数:

    create or replace 
    function F_DECRYPT_CLOB (ac_input IN CLOB) return CLOB is 
      lb_variable CLOB; 
      l_clob CLOB;
      l_blob BLOB;
      ... 
    begin 
       ...
        dbms_lob.createtemporary(l_blob, true);
    
       l_clob := replace(replace(ac_input, chr(13), null), chr(10), null);
    
       FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(l_clob) - 1 )/l_amt) LOOP
          DBMS_LOB.read(l_clob, l_amt, l_offset, l_temp);
          l_offset := l_offset + l_amt;
          l_raw    := UTL_ENCODE.base64_decode(utl_raw.cast_to_raw(l_temp));
          DBMS_LOB.append (l_blob, TO_BLOB(l_raw));
        END LOOP; 
       ...    
    end F_DECRYPT_CLOB;
    /
    

    完全に:

    create or replace 
    function F_DECRYPT_CLOB (ac_input IN CLOB) return CLOB is 
      lb_variable CLOB; 
      l_clob CLOB;
      l_blob BLOB;
      v_key RAW (320);
      v_encryption_type PLS_INTEGER := DBMS_CRYPTO.AES_CBC_PKCS5;
      v_iv RAW (320);
      l_dest_offset  PLS_INTEGER := 1;
      l_src_offset   PLS_INTEGER := 1;
      l_lang_context PLS_INTEGER := DBMS_LOB.default_lang_ctx;
      l_warning      PLS_INTEGER;
    
      l_raw     RAW(32767);
      l_amt     NUMBER := 7700;
      l_offset  NUMBER := 1;
      l_temp    VARCHAR2(32767);
      l_step PLS_INTEGER := 7700;
    
    begin 
        SELECT VALUE
         INTO v_key
         FROM algparameters
        WHERE name = 'key';
       SELECT VALUE
         INTO v_iv
         FROM algparameters
        WHERE name = 'iv';
    
        dbms_lob.createtemporary(l_blob, true);
    
       l_clob := replace(replace(ac_input, chr(13), null), chr(10), null);
    
       FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(l_clob) - 1 )/l_amt) LOOP
          DBMS_LOB.read(l_clob, l_amt, l_offset, l_temp);
          l_offset := l_offset + l_amt;
          l_raw    := UTL_ENCODE.base64_decode(utl_raw.cast_to_raw(l_temp));
          DBMS_LOB.append (l_blob, TO_BLOB(l_raw));
        END LOOP; 
    
      dbms_lob.createtemporary(lb_variable, true);
    
     sys.DBMS_CRYPTO.DECRYPT( 
                     dst => lb_variable, 
                     src => l_blob, 
                     typ => v_encryption_type,--dbms_crypto.des_cbc_pkcs5, 
                     key => v_key,
                     iv => v_iv
                     ); 
    
       return lb_variable; 
    end F_DECRYPT_CLOB;
    /
    



    1. すべてのテーブル、ストアドプロシージャ、トリガー、制約、およびすべての依存関係を1つのSQLステートメントにドロップします

    2. 不正な文字列値:'\ xEF \ xBF\xBD'列

    3. カーソルを使用せずにSQLで現在の合計を計算するにはどうすればよいですか?

    4. SELECTINでOracleパラメータを使用する際の問題