所以我有一个ORDS端点(Oracle Rest Data Services),该端点从Facebook API接收JSON负载,并在请求的标头中包含一个变量X-Hub-Signature。
我必须验证收到的请求,所以我知道它来自Facebook。
我必须生成一个哈希,以接收Facebook和我共享的有效负载(BLOB)和密钥(字符串)(app_secret),然后将其与X-Hub-Signature的值进行比较,这样我就可以确认这是一个有效的请求。
问题是,Facebook说: “请注意,我们使用有效载荷的转义的unicode版本生成签名,并使用小写的十六进制数字。如果仅根据解码的字节进行计算,则最终将获得不同的签名。例如,字符串äöå应该转义为\ u00e4 \ u00f6 \ u00e5。”到目前为止,我的哈希值与我收到的有效负载相匹配,但是我尝试使用这些äöå字符,但我不确定它是否有效,因为所有hmac在线编码器看起来都不太好,我也不会不知道(在在线编码器上)如何对它们进行Unicode编码。
到目前为止,我有这个:
FUNCTION validate_payload (p_x_hub_signature in varchar2,
p_json_payload in blob)
RETURN varchar2
IS
v_app_secret varchar2(4000) := '2f2f2f2f2f2f2f';
l_mac raw(10000);
v_x_hub_signature varchar2(4000);
BEGIN
l_mac := dbms_crypto.mac (src => p_json_payload,
typ => dbms_crypto.hmac_sh1,
key => UTL_I18N.STRING_TO_RAW (v_app_secret, 'AL32UTF8'));
v_x_hub_signature := 'sha1='||lower(l_mac);
return v_x_hub_signature;
END;
您能对此提供任何反馈吗? 这样对吗?
在此先感谢,不好意思的英语或解释!
答案 0 :(得分:0)
这是一个PL / SQL解决方案。它比Sentinel的提议所需的编码更少,并且可能更清晰。
declare
v_app_secret varchar2(100) := 'äaöå ab\ABC';
escaped varchar2(100);
item varchar2(6);
begin
escaped := replace(regexp_replace(ASCIISTR(v_app_secret), '\\([[:xdigit:]]{4})', '\u\1'), '\u005C', '\\');
for i in 1..regexp_count(escaped, '\\u[[:xdigit:]]{4}') loop
item := regexp_substr(escaped, '\\u[[:xdigit:]]{4}', 1, i);
escaped := replace(escaped, item, lower(item));
end loop;
dbms_output.put_line(escaped);
end;
\u00e4a\u00f6\u00e5 ab\\ABC
假设\
需要翻译成\\
答案 1 :(得分:0)
从@Wernfried Domscheit使用ASCIISTR
和regexp_replace
的方法开始,可以将其扩展到整个替换列表以获取小写版本:
with sample(str) as (
select 'äöå ab\ABC' from dual
), patterns(ord, pat, rep) as (
select 1, '\\A([[:xdigit:]]{3})', '\\a\1' from dual union all
select 2, '\\B([[:xdigit:]]{3})', '\\b\1' from dual union all
select 3, '\\C([[:xdigit:]]{3})', '\\c\1' from dual union all
select 4, '\\D([[:xdigit:]]{3})', '\\d\1' from dual union all
select 5, '\\E([[:xdigit:]]{3})', '\\e\1' from dual union all
select 6, '\\F([[:xdigit:]]{3})', '\\f\1' from dual union all
select 7, '\\([[:xdigit:]])A([[:xdigit:]]{2})', '\\\1a\2' from dual union all
select 8, '\\([[:xdigit:]])B([[:xdigit:]]{2})', '\\\1b\2' from dual union all
select 9, '\\([[:xdigit:]])C([[:xdigit:]]{2})', '\\\1c\2' from dual union all
select 10, '\\([[:xdigit:]])D([[:xdigit:]]{2})', '\\\1d\2' from dual union all
select 11, '\\([[:xdigit:]])E([[:xdigit:]]{2})', '\\\1e\2' from dual union all
select 12, '\\([[:xdigit:]])F([[:xdigit:]]{2})', '\\\1f\2' from dual union all
select 13, '\\([[:xdigit:]]{2})A([[:xdigit:]])', '\\\1a\2' from dual union all
select 14, '\\([[:xdigit:]]{2})B([[:xdigit:]])', '\\\1b\2' from dual union all
select 15, '\\([[:xdigit:]]{2})C([[:xdigit:]])', '\\\1c\2' from dual union all
select 16, '\\([[:xdigit:]]{2})D([[:xdigit:]])', '\\\1d\2' from dual union all
select 17, '\\([[:xdigit:]]{2})E([[:xdigit:]])', '\\\1e\2' from dual union all
select 18, '\\([[:xdigit:]]{2})F([[:xdigit:]])', '\\\1f\2' from dual union all
select 19, '\\([[:xdigit:]]{3})A', '\\\1a' from dual union all
select 20, '\\([[:xdigit:]]{3})B', '\\\1b' from dual union all
select 21, '\\([[:xdigit:]]{3})C', '\\\1c' from dual union all
select 22, '\\([[:xdigit:]]{3})D', '\\\1d' from dual union all
select 23, '\\([[:xdigit:]]{3})E', '\\\1e' from dual union all
select 24, '\\([[:xdigit:]]{3})F', '\\\1f' from dual union all
select 25, '\\([[:xdigit:]]{4})', '\u\1' from dual union all
select 26, '\\u005c', '\\\\' from dual
), recur(ord, str, tr) as (
select ord, str
, REGEXP_REPLACE(asciistr(str), pat, rep)
from sample
join patterns
on ord = 1
union all
select recur.ord+1, str
, REGEXP_REPLACE(tr, pat, rep)
from recur
join patterns
on patterns.ord = recur.ord + 1
)
select * from recur where ord = 26;
如果您希望执行PL / SQL函数,则可以嵌套一系列转换并将其放入函数中。如果您不希望将\ u005c最终转换为\,只需删除外部的regexp_replace:
create or replace function Escape_Unicode(pCLOB clob) RETURN clob is
BEGIN
return regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
asciistr(pClOB)
, '\\A([[:xdigit:]]{3})'
, '\\a\1'
)
, '\\B([[:xdigit:]]{3})'
, '\\b\1'
)
, '\\C([[:xdigit:]]{3})'
, '\\c\1'
)
, '\\D([[:xdigit:]]{3})'
, '\\d\1'
)
, '\\E([[:xdigit:]]{3})'
, '\\e\1'
)
, '\\F([[:xdigit:]]{3})'
, '\\f\1'
)
, '\\([[:xdigit:]])A([[:xdigit:]]{2})'
, '\\\1a\2'
)
, '\\([[:xdigit:]])B([[:xdigit:]]{2})'
, '\\\1b\2'
)
, '\\([[:xdigit:]])C([[:xdigit:]]{2})'
, '\\\1c\2'
)
, '\\([[:xdigit:]])D([[:xdigit:]]{2})'
, '\\\1d\2'
)
, '\\([[:xdigit:]])E([[:xdigit:]]{2})'
, '\\\1e\2'
)
, '\\([[:xdigit:]])F([[:xdigit:]]{2})'
, '\\\1f\2'
)
, '\\([[:xdigit:]]{2})A([[:xdigit:]])'
, '\\\1a\2'
)
, '\\([[:xdigit:]]{2})B([[:xdigit:]])'
, '\\\1b\2'
)
, '\\([[:xdigit:]]{2})C([[:xdigit:]])'
, '\\\1c\2'
)
, '\\([[:xdigit:]]{2})D([[:xdigit:]])'
, '\\\1d\2'
)
, '\\([[:xdigit:]]{2})E([[:xdigit:]])'
, '\\\1e\2'
)
, '\\([[:xdigit:]]{2})F([[:xdigit:]])'
, '\\\1f\2'
)
, '\\([[:xdigit:]]{3})A'
, '\\\1a'
)
, '\\([[:xdigit:]]{3})B'
, '\\\1b'
)
, '\\([[:xdigit:]]{3})C'
, '\\\1c'
)
, '\\([[:xdigit:]]{3})D'
, '\\\1d'
)
, '\\([[:xdigit:]]{3})E'
, '\\\1e'
)
, '\\([[:xdigit:]]{3})F'
, '\\\1f'
)
, '\\([[:xdigit:]]{4})'
, '\u\1'
)
, '\\u005c'
, '\\\\'
);
end;
/
select escape_unicode('äöå ab\ABCd') from dual;
答案 2 :(得分:0)
我刚刚意识到,我可能已使您误入歧途。正如Sentinel所述,v_app_secret不需要翻译,只需翻译p_json_payload(这是一个BLOB)即可。
到目前为止,我已经提出了这个建议:您认为可以吗?我没有办法确定:/
FUNCTION validate_payload (p_x_hub_signature in varchar2,
p_json_payload in blob)
RETURN varchar2
IS
v_app_secret varchar2(4000) := '3f2f2f2f23f23f23';
l_mac raw(10000);
v_x_hub_signature varchar2(4000);
BEGIN
l_mac := dbms_crypto.mac (src => UTL_I18N.STRING_TO_RAW (utl_raw.cast_to_varchar2 (p_json_payload),'AL32UTF8'),
typ => dbms_crypto.hmac_sh1,
key => UTL_I18N.STRING_TO_RAW (v_app_secret, 'AL32UTF8'));
v_x_hub_signature := 'sha1='||lower(l_mac);
dbms_output.put_line(v_x_hub_signature);
return v_x_hub_signature;
END;