【发布时间】:2020-09-23 14:36:56
【问题描述】:
我想使用 JWT 在 Jitsi 中初始化会议室。 我们的软件将为用户创建正确的 URL,以便它可以加入会议。 只有拥有正确令牌的用户才能开始会议。
url 是用 pl/sql 创建的。对于有效令牌的示例,我使用网站 jwt.io。 我编写了以下代码来创建令牌。 令牌的第一部分是正确的。只有签名不匹配。我想我错过了类型转换或变量 l_content 的类型错误。 我做错了什么?
l_token varchar2(30000);
l_header varchar2(1000);
l_header_base64 raw (1000);
l_payload varchar2(10000);
l_payload_base64 raw(10000);
l_signature varchar2(30000);
l_secretkey string(32767) :='your-256-bit-secret';
l_content string(32767);
l_content_raw raw(30000);
l_point raw(1);
l_charset varchar2(8) := 'AL32UTF8';
l_crlf varchar2(2) := chr(13) || chr(10);
l_pay_clean varchar2(10000);
l_hdr_clean varchar2(10000);
begin
sys.dbms_output.put_line('Token from JWT.io: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c');
l_point := utl_i18n.string_to_raw( '.', l_charset);
--
--
-- maak header middels json en base64 encode
select json_object ('alg' value 'HS256'
,'typ' value 'JWT')
into l_header
from dual;
select json_object ('sub' value '1234567890'
,'name' value 'John Doe'
,'iat' value 1516239022)
into l_payload
from dual;
l_header_base64 := utl_encode.base64_encode(utl_raw.cast_to_raw(l_header));
l_payload_base64 := utl_encode.base64_encode(utl_raw.cast_to_raw(l_payload));
l_hdr_clean := replace(replace(utl_raw.cast_to_varchar2(l_header_base64),l_crlf), '==');
l_pay_clean := replace(replace(utl_raw.cast_to_varchar2(l_payload_base64),l_crlf), '==');
sys.dbms_output.put_line('l_hdr_clean: ' || l_hdr_clean);
sys.dbms_output.put_line('l_pay_clean: ' || l_pay_clean);
l_content := l_hdr_clean || '.' ||l_pay_clean;
sys.dbms_output.put_line('l_content: ' || l_content);
l_signature := dbms_crypto.mac(UTL_I18N.string_to_raw(l_content, l_charset)
,dbms_crypto.hmac_sh256
,utl_i18n.string_to_raw(l_secretkey, l_charset));
sys.dbms_output.put_line('l_signature:' || l_signature);
return l_hdr_clean||'.'||l_pay_clean||'.'||l_signature;
end;
【问题讨论】:
-
签名是什么样子的?我不知道这是否已经解决了问题,但至少您还需要对签名进行 base64url 编码。
-
签名是现在这个样子:49F94AC7044948C78A285D904F87F0A4C7897F7E8F3A4EB2255FDA750B2CC397,它应该是这样的:SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c,如果我使用Base64编码添加到MAC的TE结果它也不起作用,或者是这不是你的意思? utl_encode.base64_encode(dbms_crypto.mac(UTL_I18N.string_to_raw(l_content, l_charset),dbms_crypto.hmac_sh256,utl_i18n.string_to_raw(l_secretkey, l_charset)));
-
这是哈希的十六进制表示。请参考this answer,基本相同的问题,只是涉及的语言不同。您需要的是 base64url 编码哈希值本身(而不是它的十六进制字符串表示)
-
你得到的可能与链接答案中在线哈希工具的结果相同。
-
感谢文章的链接。对我来说,看起来我做了同样的事情: var base64Signature = CryptoJS.HmacSHA256(base64Header + "." + base64Payload , secret).toString(CryptoJS.enc.Base64).replace(/\+/g,'- ').replace(/\=+$/m,'');通过在函数周围添加 utl_encode.base64_encode 来创建哈希值。除非它不是 url 编码函数。我不知道如何在 oracle pl/sql 中创建它。