让 Oracle 的 MD5 与 PHP 的 MD5 匹配

Posted

技术标签:

【中文标题】让 Oracle 的 MD5 与 PHP 的 MD5 匹配【英文标题】:Getting Oracle's MD5 to match PHP's MD5 【发布时间】:2010-11-16 18:05:01 【问题描述】:

我正在尝试将 php 生成的 MD5 校验和与 Oracle 10g 生成的校验和进行比较。但是,我似乎在将苹果与橙子进行比较。

这是我为测试比较所做的:

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

Oracle 中的 md5 函数(见上面的查询)使用 'dbms_obfuscation_toolkit.md5' 包(?),定义如下:

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;

我的 PHP 页面上显示的是:

29dbb90ea99a397b946518c84f45e016

)Û¹©š9”eÈOEà 

谁能帮我让两者匹配?

【问题讨论】:

【参考方案1】:

创建如下函数:

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;

然后这样称呼它:

select md5('foobar') from dual;

似乎“dbms_obfuscation_toolkit.md5”并没有真正以原始格式返回,因此需要调用“utl_raw.cast_to_raw”。不过我可能是错的,对此应该有更好的解释。

【讨论】:

【参考方案2】:

我得到相同的“数字或值错误”,发现两个函数一起工作:

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;

然后您可以运行此查询来获取您的校验和:

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

第二个函数的作用与在您提供的函数上发出 Bazz 提供的 SELECT 语句相同,但我更喜欢不必在每个查询中执行 rawToHex --> 较低的转换。每次使用查询时,都会有太多事情可能出错。我认为它也可能更快,因为它是在创建时而不是在运行时编译的,但我可能错了。

【讨论】:

【参考方案3】:

如果您想在 Oracle 中使用 md5,可以使用此方法:

select lower(rawtohex(md5hash('foobar'))) from dual

【讨论】:

当我尝试像这样包装我的电话时 - rawtohex(dbms_obfuscation_toolkit.md5(input_string => TEXT)) - 它告诉我“数字或值错误:十六进制到原始转换错误”,这很有趣,因为我正在尝试将原始转换为十六进制而不是十六进制转换为原始。【参考方案4】:

它返回原始字节,您需要将其转换为十六进制。

$x = unpack("H*", $row[0]); 
echo $x[1];

【讨论】:

【参考方案5】:

看来,从 Oracle 查询打印的内容是 md5 校验和的原始字节流,因为这些八位字节中的大多数不是 ascii 字符而被损坏。请先尝试将其转换为十六进制。

【讨论】:

以上是关于让 Oracle 的 MD5 与 PHP 的 MD5 匹配的主要内容,如果未能解决你的问题,请参考以下文章

为啥 php md5 与 用 js md5 加密出来的结果不一样,怎么解决,使

如何使php的MD5与C#的MD5一致?

有关MD5与PHP,高手进

PHP中的md5与Java中的md5加密结果不一致问题

java的32位MD5加密与php中的32位MD5加密结果不一样.求帮助

CTF_Web:php弱类型绕过与md5碰撞