I have created this function for decrypt a password and its working but is showing strange characters like this ��5d[���������. I'm using oracle xe 10g
create or replace
function decrypt (val VARCHAR) return varchar2 is
input_string varchar2(2048) := val;
key_string VARCHAR2(10) := 'xpto';
decrypted_string VARCHAR2(2048);
begin
dbms_output.put_line(input_string);
dbms_obfuscation_toolkit.DESDecrypt(
input_string => input_string,
key_string => key_string,
decrypted_string => decrypted_string );
dbms_output.put_line('> decrypted string output : ' || decrypted_string);
return decrypted_string;
end;
What i'm i doing wrong it should appear a readable string.
Why would you need to decode a password? Why not store it hashed?
There are a few constraints with the size of the input string and the key size as well (explained in the online doc).
Here's a working example with Oracle 10.2.0.3:
SQL> VARIABLE v_in VARCHAR2(64);
SQL> VARIABLE v_enc VARCHAR2(64);
SQL> VARIABLE v_out VARCHAR2(64);
SQL> DECLARE
2 l_key VARCHAR2(8) := rpad('my_key', 8, 'x'); -- 64-bit key
3 BEGIN
4 -- input size must be a multiple of 8 bytes
5 :v_in := '12345678';
6 :v_enc := dbms_obfuscation_toolkit.desEncrypt(input_string => :v_in,
7 key_string => l_key);
8 :v_out := dbms_obfuscation_toolkit.desDecrypt(input_string => :v_enc,
9 key_string => l_key);
10 END;
11 /
PL/SQL procedure successfully completed
v_in
---------
12345678
v_enc
---------
þæHI«Ó¹-
v_out
---------
12345678
Related
I am trying to take a ROWTYPE, RECORD, or OBJECT type and dynamically convert it to a single string representation.
I want to do this dynamically.
Update: Doing this for an OBJECT type now working thanks to Justin Cave's feedback.
Example Data:
ID | VAL
---------
1 | BOB
Desired Output:
ID=1, VAL=BOB
Error Received:
ORA-06550: line 7, column 25:
PLS-00306: wrong number or types of arguments in call to 'TO_STRING'
ORA-06550: line 7, column 4:
PL/SQL: Statement ignored
What I have so Far (Doesn't loop through columns yet.):
CREATE OR REPLACE FUNCTION to_string (
ip_anydata in out anydata --note the "out" - this is required for the "piecewise"
)
RETURN VARCHAR2
IS
lv_typecode PLS_INTEGER;
lv_anytype anytype;
BEGIN
DBMS_OUTPUT.PUT_LINE('[Expected='||dbms_types.typecode_object||', Actual='||ip_anydata.getType(lv_anytype)||']');
--Get the typecode, and the ANYTYPE
lv_typecode := ip_anydata.getType(lv_anytype);
--Check that it's really an object
IF lv_typecode = dbms_types.typecode_object
THEN
--If it is an object, find the first item
DECLARE
lv_first_attribute_typecode pls_integer;
lv_aname varchar2(32767);
lv_result pls_integer;
lv_varchar varchar2(32767);
--Variables we don't really care about, but need for function output
lv_prec pls_integer;
lv_scale pls_integer;
lv_len pls_integer;
lv_csid pls_integer;
lv_csfrm pls_integer;
lv_attr_elt_type anytype;
BEGIN
lv_first_attribute_typecode := lv_anytype.getAttrElemInfo(
pos => 1, --First attribute
prec => lv_prec,
scale => lv_scale,
len => lv_len,
csid => lv_csid,
csfrm => lv_csfrm,
attr_elt_type => lv_attr_elt_type,
aname => lv_aname
);
--Check typecode of attribute
IF lv_first_attribute_typecode = dbms_types.typecode_varchar2
THEN
--Now that we've verified the type, get the actual value.
ip_anydata.piecewise;
lv_result := ip_anydata.getVarchar2(c => lv_varchar);
--DEBUG: Print the attribute name, in case you're curious
--dbms_output.put_line('lv_aname: '||lv_aname);
RETURN lv_aname||'='||lv_varchar;
ELSE
raise_application_error(-20000, 'Unexpected 1st Attribute Typecode: '||lv_first_attribute_typecode);
END IF;
END;
ELSE
raise_application_error(-20000, 'Unexpected Typecode: '||lv_typecode);
END IF;
END;
/
Scenario#1 - Select INTO w/ ROWTYPE:
DECLARE
lv_cv dual%ROWTYPE;
lv_str VARCHAR2(32767);
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------------------');
SELECT * INTO lv_cv FROM dual WHERE ROWNUM <= 1;
DBMS_OUTPUT.PUT_LINE(to_string(lv_cv));
END;
/
Scenario#2 - FETCH INTO w/ Cursor ROWTYPE:
DECLARE
CURSOR cv_cur IS SELECT * FROM dual WHERE ROWNUM <= 1;
lv_cv cv_cur%ROWTYPE;
lv_str VARCHAR2(32767);
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------------------');
OPEN cv_cur;
FETCH cv_cur INTO lv_cv;
CLOSE cv_cur;
DBMS_OUTPUT.PUT_LINE(to_string(lv_cv));
END;
/
Scenario#3 - Regular OBJECT: (Updated)
DECLARE
lv_cv T_CODE_VAL_REC := T_CODE_VAL_REC('BOB', 5);
lv_str VARCHAR2(32767);
lv_any ANYDATA;
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------------------');
lv_any := sys.anydata.ConvertObject(lv_cv);
DBMS_OUTPUT.PUT_LINE(to_string(lv_any));
EXCEPTION WHEN OTHERS THEN
pts2_test_valitation_util.fail(999, CHR(10)||CHR(10)||'Unexpected Error:'||CHR(10)||SQLERRM||CHR(10)||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END;
/
I am being given a large encrypted file containing 10 million rows of data.
I need to load this into an oracle database (in it's encrypted form) and then decrypt it in the database using pl/sql and the oracle built-in dbms_crypto.
I then need to process the unencrypted LOB to seperate out the 10 Million rows.
I will have the public key for the file. The file will be about 5GB in size.
Is this possible using just pl/sql? (and the oracle built-ins)
Has anyone had any experience of doing this sort of thing? - any pointers will be most welcome.
Thanks
this works for me.
SYS has to:
GRANT EXECUTE ON DBMS_CRYPTO TO <user>
in user :
CREATE OR REPLACE DIRECTORY
CRYPTDIR AS
'<crypted files directory>';
CREATE TABLE TESTCRYPT (ID INTEGER, E BLOB, D BLOB);
CREATE OR REPLACE FUNCTION load_Blob_FromFile(p_file_name VARCHAR2)
RETURN BLOB
AS
dest_loc BLOB := empty_blob();
src_loc BFILE := BFILENAME('CRYPTDIR', p_file_name);
BEGIN
-- Open source binary file from OS
DBMS_LOB.OPEN(src_loc, DBMS_LOB.LOB_READONLY);
-- Create temporary LOB object
DBMS_LOB.CREATETEMPORARY(
lob_loc => dest_loc
, cache => true
, dur => dbms_lob.session
);
-- Open temporary lob
DBMS_LOB.OPEN(dest_loc, DBMS_LOB.LOB_READWRITE);
-- Load binary file into temporary LOB
DBMS_LOB.LOADFROMFILE(
dest_lob => dest_loc
, src_lob => src_loc
, amount => DBMS_LOB.getLength(src_loc));
-- Close lob objects
DBMS_LOB.CLOSE(dest_loc);
DBMS_LOB.CLOSE(src_loc);
-- Return temporary LOB object
RETURN dest_loc;
END;
/
INSERT INTO TESTCRYPT
(ID, E)
SELECT 1, LOAD_BLOB_FROMFILE('EncryptedFile') FROM DUAL;
CREATE OR REPLACE FUNCTION DCRYPT2(TO_DECRYPT IN BLOB) RETURN BLOB
IS
DECRYPTED BLOB;
v_key PLS_INTEGER :=
DBMS_CRYPTO.ENCRYPT_AES128 +
DBMS_CRYPTO.CHAIN_ECB +
DBMS_CRYPTO.PAD_PKCS5;
BEGIN
dbms_lob.createtemporary(DECRYPTED,true);
DBMS_CRYPTO.DECRYPT(DECRYPTED,
TO_DECRYPT,
v_key,
'<Hex-Key>'
);
RETURN DECRYPTED;
END;
UPDATE TESTCRYPT SET D = DCRYPT2(E) WHERE ID=1;
CREATE OR REPLACE FUNCTION PADIS_MASTER.blob2clob (p_in blob) RETURN clob IS
v_clob clob;
v_varchar VARCHAR2(32767);
v_start PLS_INTEGER := 1;
v_buffer PLS_INTEGER := 32767;
BEGIN
dbms_lob.createtemporary(v_clob, TRUE);
FOR i IN 1..CEIL(dbms_lob.getlength(p_in) / v_buffer)
LOOP
v_varchar := utl_raw.cast_to_varchar2(dbms_lob.SUBSTR(p_in, v_buffer, v_start));
dbms_lob.writeappend(v_clob, LENGTH(v_varchar), v_varchar);
v_start := v_start + v_buffer;
END LOOP;
RETURN v_clob;
END;
/
SELECT BLOB2CLOB(D) FROM TESTCRYPT WHERE ID = 1;
for example Oracle 11 compiles with this key: 'b1b7adc285e82db81ea17f7be706e4f7'
at last the encryption function:
CREATE OR REPLACE FUNCTION ECRYPT(TO_CRYPT IN BLOB) RETURN BLOB
IS
CRYPTED BLOB;
v_key PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES128
+ DBMS_CRYPTO.CHAIN_ECB
+ DBMS_CRYPTO.PAD_PKCS5;
BEGIN
dbms_lob.createtemporary(AUSGABE,true);
DBMS_CRYPTO.ENCRYPT(CRYPTED,
TO_CRYPT,
v_key,
'b1b7adc285e82db81ea17f7be706e4f7'
);
RETURN CRYPTED;
END;
I have a varchar2 field and want to split it to array of chars
Like 'ABCDEF' --> 'A' 'B' 'C' 'D' 'E'
How can i convert my Field Values to chars array?
If you actually mean a PL/SQL collection of characters, you could do something like
SQL> ed
Wrote file afiedt.buf
1 declare
2 type char_arr is table of char(1) index by pls_integer;
3 l_str varchar2(100) := 'ABCDEF';
4 l_arr char_arr;
5 begin
6 for i in 1 .. length(l_str)
7 loop
8 l_arr(i) := substr( l_str, i, 1 );
9 end loop;
10 dbms_output.put_line( l_arr.count );
11* end;
SQL> /
6
PL/SQL procedure successfully completed.
Without understanding the business requirements, though, I would tend to be very suspicious. When you find yourself breaking apart strings in PL/SQL, that almost always implies that you have stored data in a non-atomic form and need to address the data model issue.
when using oracle forms to generate md5 hash, i get result that is different from the result given by tomcat.
when using tomcat digest, i get:
C:\apache-tomcat-6.0.26\bin>digest -a md5 mypass
mypass:a029d0df84eb5549c641e04a9ef389e5
while using oracle forms, i get:
a029d0dfbfeb5549c641e04abff3bfe5
this is the code:
Declare
v_checksum varchar2( 32 );
v_hex_value varchar2( 32 );
begin
v_checksum := SYS.DBMS_OBFUSCATION_TOOLKIT.MD5( input_string => 'mypass' );
SELECT LOWER( RAWTOHEX( v_checksum ) )
INTO v_hex_value
FROM dual;
:res := v_hex_value;
end;
why aren't they giving the same result ? is there something wrong with my code ?
which version of Oracle are you running ? Your code gives the good answer on 10.2.0.3.0:
SQL> VARIABLE res VARCHAR2(32);
SQL> Declare
2 v_checksum varchar2( 32 );
3 v_hex_value varchar2( 32 );
4 begin
5 v_checksum:=SYS.DBMS_OBFUSCATION_TOOLKIT.MD5(input_string=>'mypass');
6
7
8 SELECT LOWER( RAWTOHEX( v_checksum ) )
9 INTO v_hex_value
10 FROM dual;
11
12 :res := v_hex_value;
13 end;
14 /
PL/SQL procedure successfully completed
res
---------
a029d0df84eb5549c641e04a9ef389e5
Also I tried the other MD5 functions and they give the same answer:
SQL> DECLARE
2 l_input RAW(16) := utl_raw.cast_to_raw('mypass');
3 BEGIN
4 :res:=lower(rawtohex(dbms_obfuscation_toolkit.md5(input=>l_input)));
5 END;
6 /
PL/SQL procedure successfully completed
res
---------
a029d0df84eb5549c641e04a9ef389e5
Your code seems correct
I also get a029d0df84eb5549c641e04a9ef389e5 here http://md5hashgenerator.com/index.php
and also in sql server I get the same
SELECT CONVERT(VARCHAR(32),HashBytes('MD5', 'mypass'),2)
I have a stored procedure with an IN OUT parameter declared like follows:
create or replace PROCEDURE RIFATT_SEGN0_INS(pIdRifattSegn0 in OUT NUMBER,
pNumDossier IN VARCHAR2 ,
pNumConsegna IN NUMBER,
pDtConsegna IN DATE,
[..]
) AS
[..]
Whenever i call it from another procedure, how do i get the pIdRifattSegn0 parameter that is also out?
Your question isn't entirely clear. An IN OUT parameter is passed both ways, as its name implies. This means it has to be passed a variable, not a literal and you need a declare block to do that. For example:
declare
l_segn number;
begin
l_segn := 1;
-- procedure will have received value = 1
rifatt_segn0_ins(l_segn, 'x', 2, sysdate);
-- procedure may have changed value of l_segn from 1 to something else
dbms_output.put_line(l_segn);
end;
Here is an example:
SQL> create or replace PROCEDURE RIFATT_SEGN0_INS
2 ( pIdRifattSegn0 IN OUT NUMBER
3 , pNumDossier IN VARCHAR2
4 , pNumConsegna IN NUMBER
5 , pDtConsegna IN DATE
6 )
7 as
8 begin
9 dbms_output.put_line(pNumDossier);
10 dbms_output.put_line(to_char(pNumConsegna));
11 dbms_output.put_line(to_char(pDtConsegna,'yyyy-mm-dd'));
12 pIdRifattSegn0 := sqrt(pIdRifattSegn0);
13 end;
14 /
Procedure is aangemaakt.
SQL> create or replace procedure another_procedure
2 as
3 l_IdRifattSegn0 number := 4;
4 begin
5 rifatt_segn0_ins
6 ( pIdRifattSegn0 => l_IdRifattSegn0
7 , pNumDossier => '1A'
8 , pNumConsegna => 42
9 , pDtConsegna => sysdate
10 );
11 dbms_output.put_line('from another_procedure: l_IdRifattSegn0 = ' || to_char(l_IdRifattSegn0));
12 end;
13 /
Procedure is aangemaakt.
SQL> exec another_procedure
1A
42
2009-05-21
from another_procedure: l_IdRifattSegn0 = 2
PL/SQL-procedure is geslaagd.
Regards,
Rob.