因此,我在Microsof SQL Server中拥有此存储过程,该存储过程采用2个参数(密码和salt)并生成base64binary。我想在Oracle中转移这种逻辑
[{'Next': {'Next': 'he,get',
'seed': [{'Argument': [{'id': 4, 'label': 'org'},
{'id': 'I'},
{'id': 3, 'label': 'object', 'seed': 2, 'word': 'He'},
{'id': 2, 'label': 'verb', 'seed': 9, 'word': 'Gets'},
{'id': 1, 'label': ''},
{'id': 4, 'label': ''},
{'id': 4, 'label': ''}]}],
'time': ''}}]
样品数据:
@password = ...
set @source = hashbytes('sha2_256',@password + @Salt)
set @encrypted=( select cast(N'' as xml).value('xs:base64Binary(sql:variable("@source"))', 'varchar(max)'))
...
和@salt = 1234567890123456
@source将为TESTTEST
和@encrypted将为0xC1DB209FD3B6873B0F35C2FB103CCC5E9C585C26F79048D575318AA70E17F07F
尝试实现这一点,我在oracle中看到hash2有点复杂,所以我认为尝试不当,至少要做base64binary部分。
我尝试了这种方法(以及其他一些方法),这是我在SO的其他问题中发现的
wdsgn9O2hzsPNcL7EDzMXpxYXCb3kEjVdTGKpw4X8H8=
但是通过传递我从MS SQL第一步中获得的@source值,我得到了不同的编码字符串。
Oracle中是否有类似的东西?我该怎么办?
答案 0 :(得分:3)
您可以使用dbms_crypto.hash()
对密码+盐值进行哈希处理;您需要先将其转换为raw
,结果也是raw
。
然后将raw
的哈希值转换为base64,后者仍为raw
;然后将其转换为varchar2
。
declare
l_password varchar2(30) := '1234567890123456';
l_salt varchar2(30) := 'TESTTEST';
l_raw raw(256);
l_hash raw(256);
l_base64_raw raw(256);
l_base64 varchar2(256);
begin
l_raw := utl_i18n.string_to_raw(data => l_password || l_salt, dst_charset => 'AL32UTF8');
l_hash := dbms_crypto.hash(src => l_raw, typ => dbms_crypto.hash_sh256);
dbms_output.put_line(l_hash);
l_base64_raw := utl_encode.base64_encode(l_hash);
dbms_output.put_line(l_base64_raw);
l_base64 := utl_raw.cast_to_varchar2(l_base64_raw);
dbms_output.put_line(l_base64);
end;
/
C1DB209FD3B6873B0F35C2FB103CCC5E9C585C26F79048D575318AA70E17F07F
776473676E394F32687A73504E634C3745447A4D58707859584362336B456A566454474B707734583848383D
wdsgn9O2hzsPNcL7EDzMXpxYXCb3kEjVdTGKpw4X8H8=
PL/SQL procedure successfully completed.
或者作为一个功能,稍微简化一下:
create or replace function hash_base64 (p_password varchar2, p_salt varchar2)
return varchar2
is
l_raw raw(256);
l_hash raw(256);
l_base64 varchar2(256);
begin
l_raw := utl_i18n.string_to_raw(data => p_password || p_salt, dst_charset => 'AL32UTF8');
l_hash := dbms_crypto.hash(src => l_raw, typ => dbms_crypto.hash_sh256);
l_base64 := utl_raw.cast_to_varchar2(r => utl_encode.base64_encode(l_hash));
return l_base64;
end;
/
select hash_base64 ('1234567890123456', 'TESTTEST') from dual;
HASH_BASE64('1234567890123456','TESTTEST')
--------------------------------------------------
wdsgn9O2hzsPNcL7EDzMXpxYXCb3kEjVdTGKpw4X8H8=
我认为您正在做的问题是您将source
值作为字符串传递,然后将该字符串转换为raw
;也就是说,您正在传递字符串值'C1DB2...'
并将其强制转换为raw
,而不是传递该raw
值。
因此,您可以有效地执行以下操作:
declare
l_base64 varchar2(256);
begin
l_base64 := utl_raw.cast_to_varchar2(
utl_encode.base64_encode(
utl_raw.cast_to_raw('C1DB209FD3B6873B0F35C2FB103CCC5E9C585C26F79048D575318AA70E17F07F')));
dbms_output.put_line(l_base64);
end;
/
得到
QzFEQjIwOUZEM0I2ODczQjBGMzVDMkZCMTAzQ0NDNUU5QzU4NUMyNkY3OTA0OEQ1NzUzMThBQTcwRTE3RjA3Rg==
或者您可能添加了0x
前缀,该前缀为:
MHhDMURCMjA5RkQzQjY4NzNCMEYzNUMyRkIxMDNDQ0M1RTlDNTg1QzI2Rjc5MDQ4RDU3NTMxOEFBNzBFMTdGMDdG
您可以将其作为raw
文字传递,而不是将字符串强制转换为raw
:
declare
l_base64 varchar2(256);
begin
l_base64 := utl_raw.cast_to_varchar2(
utl_encode.base64_encode('C1DB209FD3B6873B0F35C2FB103CCC5E9C585C26F79048D575318AA70E17F07F'));
dbms_output.put_line(l_base64);
end;
/
wdsgn9O2hzsPNcL7EDzMXpxYXCb3kEjVdTGKpw4X8H8=