tags:

views:

1990

answers:

5

Hi all,

I'm trying to compare an MD5 checksum generated by PHP to one generated by Oracle 10g. However it seems I'm comparing apples to oranges.

Here's what I did to test the comparison:

//md5 tests

  //php md5
  print md5('testingthemd5function');

  print '<br/><br/>';

  //oracle md5
  $md5query = "select md5hash('testingthemd5function') from dual";

  $stid = oci_parse($conn, $md5query);
  if (!$stid) {
   $e = oci_error($conn);
   print htmlentities($e['message']);
   exit;
  }

  $r = oci_execute($stid, OCI_DEFAULT);
  if (!$r) {
   $e = oci_error($stid);
   echo htmlentities($e['message']);
   exit;
  }

  $row = oci_fetch_row($stid); 
  print $row[0];

The md5 function (seen in the query above) in Oracle uses the 'dbms_obfuscation_toolkit.md5' package(?) and is defined like this:

CREATE OR REPLACE FUNCTION PORTAL.md5hash (v_input_string in varchar2) return varchar2     
is
   v_checksum varchar2(20);
   begin
   v_checksum := dbms_obfuscation_toolkit.md5 (input_string => v_input_string);
   return v_checksum;
end;

What comes out on my PHP page is:

29dbb90ea99a397b946518c84f45e016

)Û¹©š9{”eÈOEà

Can anyone help me in getting the two to match?

+7  A: 

It appears that what's being printed from the Oracle query is the raw bytestream of the md5 checksum, mangled because most of those octets won't be ascii characters. Try converting it to hexadecimal first.

Meredith L. Patterson
+10  A: 

It returns raw bytes, you need to convert that into hex.

$x = unpack("H*", $row[0]); 
echo $x[1];
OneOfOne
thanks, that worked like a charm
Zenshai
+1  A: 

In case you would want to have the md5 in Oracle, you can use this method:

select lower(rawtohex(md5hash('foobar'))) from dual
Bazz
When I try wrapping my call like that - rawtohex(dbms_obfuscation_toolkit.md5(input_string => TEXT)) - it tells me "numeric or value error: hex to raw conversion error", which is funny since I'm trying to convert raw to hex not hex to raw.
eidylon
A: 

I got the same "numeric or value error" and found that two functions together work:

CREATE OR REPLACE FUNCTION MD5RAW( v_input_string in varchar2 )
RETURN varchar2 IS
v_checksum varchar2( 32 );
BEGIN
    v_checksum := SYS.DBMS_OBFUSCATION_TOOLKIT.MD5( input_string => v_input_string );
    return v_checksum;
END;

CREATE OR REPLACE FUNCTION MD5HEX( v_input_string in varchar2 )
RETURN varchar2 IS
v_hex_value varchar2( 32 );
BEGIN
    SELECT  LOWER( RAWTOHEX( MD5RAW( v_input_string ) ) ) 
    INTO    v_hex_value
    FROM    dual;
    return v_hex_value;
END;

Then you can run this query to get your checksum:

SELECT md5hex( 'my string smoked your hash' ) FROM dual;

That second function does the same thing as issuing the SELECT statement provided by Bazz on the function you provide, but I prefer to not have to do the rawToHex --> lower conversion inside of every query. That leaves too many things to potentially go wrong every time you use the query. I think it may be faster too since it is compiled at creation time instead of at runtime, but I may be wrong about that.

costmo
A: 

Create a function like the following:

create or replace
function md5( input varchar2 ) return sys.dbms_obfuscation_toolkit.varchar2_checksum as
begin
    return lower(rawtohex(utl_raw.cast_to_raw(sys.dbms_obfuscation_toolkit.md5( input_string => input ))));
end;

and call it like this:

select md5('foobar') from dual;

it seems that "dbms_obfuscation_toolkit.md5" does not really return in raw format, hence the need to call "utl_raw.cast_to_raw". I could be wrong though, there should be a better explanation for this.

aswardly