Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Błąd podczas używania funkcji DBMS_CRYPTO do odszyfrowywania danych CLOB

Błąd pochodzi z linii 33, czyli:

l_raw    := UTL_ENCODE.base64_decode(l_temp);

base64_decode funkcja oczekuje argumentu RAW, więc możesz przekonwertować łańcuch, który masz teraz:

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

tj.

   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; 

Twój łańcuch base-64 ma podziały wierszy; oni wyrzucają dekodowanie. Możesz użyć mniejszego rozmiaru porcji, z l_amt = 64 i pomiń podziały wierszy:

   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;

ale prawdopodobnie prostsze i bardziej wydajne jest rozebranie ich wszystkich za jednym razem, za pomocą nowego l_clob zmienna:

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;
/

W całości:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tworzenie wyzwalacza w Oracle Express

  2. Konwersja znacznika czasu w Oracle dla formatu RRRR-MM-DD GG:MM:SS

  3. Jak uzyskać wiek z daty w Oracle

  4. Używanie LogMiner do znajdowania bieżących zmian

  5. Oracle PL/SQL - Jak uniknąć dwukropka (:), błędnie interpretowanego dla zmiennej wiążącej?