输入Oracle中的base64binary

时间:2018-07-25 09:52:10

标签: oracle hash plsql base64

因此,我在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中是否有类似的东西?我该怎么办?

1 个答案:

答案 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=