您的位置:首页 > 数据库 > Oracle

(转)Oracle、SQL Server下MD5+Base64密码加密实现

2011-09-18 13:03 891 查看
转自:http://blog.csdn.net/lele5000/article/details/6704247

写在前面:

MD5和Base64的函数实现并不是本文的重点,重点是在实现过程中遇到的字符集转换的麻烦

最近由于工作需要,要将BIEE与公司现有的ERP系统做集成,使用外部表的方式。

现有系统基于.Net平台,数据库为SQL Server 2008 R2,用户密码采用先算MD5在转Base64的方式存于数据库中。

代码逻辑如下

view plaincopy to clipboardprint?
byte[] byteString = null;
MD5 md5 = MD5.Create();
byteString = md5.ComputeHash(Encoding.Unicode.GetBytes(Str));
md5.Clear();
string NewStr = Convert.ToBase64String(byteString);
view plaincopy to clipboardprint?
SQL> select utl_raw.cast_to_varchar2(utl_encode.base64_encode(GET_MD5('qaz123'))) from dual;

UTL_RAW.CAST_TO_VARCHAR2(UTL_E
--------------------------------------------------------------------------------
NPhcqA7DU9MFK4otOXOgxQ==
SQL> select utl_raw.cast_to_varchar2(utl_encode.base64_encode(GET_MD5('qaz123'))) from dual;

UTL_RAW.CAST_TO_VARCHAR2(UTL_E
--------------------------------------------------------------------------------
NPhcqA7DU9MFK4otOXOgxQ==


SQL Server:

view plaincopy to clipboardprint?
select dbo.f_ToBase64(hashbytes('MD5',convert(NVARCHAR,'qaz123')))

LwUQYUuskyOhnZXD8WUh8Q==
view plaincopy to clipboardprint?
select utl_raw.cast_to_varchar2(utl_encode.base64_encode(GET_MD5(N'qaz123'))) from dual;

UTL_RAW.CAST_TO_VARCHAR2(UTL_E
--------------------------------------------------------------------------------
NPhcqA7DU9MFK4otOXOgxQ==
select utl_raw.cast_to_varchar2(utl_encode.base64_encode(GET_MD5(N'qaz123'))) from dual;

UTL_RAW.CAST_TO_VARCHAR2(UTL_E
--------------------------------------------------------------------------------
NPhcqA7DU9MFK4otOXOgxQ==


直到我把其转为UTF16LE,结果才和C#中的一样

注:Oracle中的UTF16默认为UTF16BE

view plaincopy to clipboardprint?
select utl_raw.cast_to_varchar2(utl_encode.base64_encode(GET_MD5(convert('qaz123','AL16UTF16LE')))) from dual;

UTL_RAW.CAST_TO_VARCHAR2(UTL_E
--------------------------------------------------------------------------------
LwUQYUuskyOhnZXD8WUh8Q==
view plaincopy to clipboardprint?
SQL> select 'UTF8',dump('qaz123') from dual
2  union all
3  select 'UTF16BE',dump(N'qaz123') from dual
4  union all
5  select 'UTF16LE', dump(convert('qaz123','AL16UTF16LE')) from dual
6  ;

'UTF8'  DUMP('QAZ123')
------- ----------------------------------------------
UTF8    Typ=96 Len=6: 113,97,122,49,50,51
UTF16BE Typ=96 Len=12: 0,113,0,97,0,122,0,49,0,50,0,51
UTF16LE Typ=1 Len=12: 113,0,97,0,122,0,49,0,50,0,51,0
SQL> select 'UTF8',dump('qaz123') from dual
2  union all
3  select 'UTF16BE',dump(N'qaz123') from dual
4  union all
5  select 'UTF16LE', dump(convert('qaz123','AL16UTF16LE')) from dual
6  ;

'UTF8'  DUMP('QAZ123')
------- ----------------------------------------------
UTF8    Typ=96 Len=6: 113,97,122,49,50,51
UTF16BE Typ=96 Len=12: 0,113,0,97,0,122,0,49,0,50,0,51
UTF16LE Typ=1 Len=12: 113,0,97,0,122,0,49,0,50,0,51,0



下面给出Oracle和SQL Server下的相关函数实现代码

Oracle:

创建MD5函数

view plaincopy to clipboardprint?
CREATE OR REPLACE FUNCTION GET_MD5
( p_str in varchar2)
RETURN varchar2 IS
BEGIN
RETURN Utl_Raw.Cast_To_Raw(DBMS_OBFUSCATION_TOOLKIT.MD5(input_string => lower(P_Str)));
END;
view plaincopy to clipboardprint?
select utl_raw.cast_to_varchar2(utl_encode.base64_encode(GET_MD5(convert('qaz123','AL16UTF16LE')))) from dual;
select utl_raw.cast_to_varchar2(utl_encode.base64_encode(GET_MD5(convert('qaz123','AL16UTF16LE')))) from dual;


SQL Server:

从SQL Server 2005开始,其自带了hashbytes函数用于生成字符串的Hash值,所以MD5这一步就可以直接采用现有的函数了。

至于转换成Base64,系统并没有提供相关函数,不过我们有变通的方法,原理是SQL Server使用FOR XML 生成xml 实例时,binary 数据使用base64 编码

函数如下:

view plaincopy to clipboardprint?
create function f_ToBase64
(@bin varbinary(max))
returns varchar(max)
as begin
return cast(N'' as xml).value('xs:base64Binary(xs:hexBinary(sql:variable("@bin")))', 'varchar(max)')
end
view plaincopy to clipboardprint?
select dbo.f_ToBase64(hashbytes('MD5',convert(NVARCHAR,'qaz123')))
select dbo.f_ToBase64(hashbytes('MD5',convert(NVARCHAR,'qaz123')))

特别需要注意红色部分,这是为了和C#代码逻辑保持一致。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: