【问题标题】:Encode JWT token in Oracle PL/SQL在 Oracle PL/SQL 中编码 JWT 令牌
【发布时间】: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 中创建它。

标签: oracle plsql jwt token


【解决方案1】:

这是在 jps 帮助下的最终解决方案:

function cleanup_base64 (p_base in raw) return varchar2
    is
            l_return varchar2(32767);
            l_crlf   varchar2(2) := chr(13) || chr(10);
            l_base   varchar2(32767);
    begin
            l_base   := utl_i18n.raw_to_char (p_base, CONVERT_CHARSET);
            l_base   := replace(replace(replace(replace(l_base,l_crlf), '='),'+', '-'), '/', '_');
            l_return := l_base;

            return l_return;
    end;


 function generate_jitsi_token (p_naam in varchar2) return varchar2
    is

        l_token             varchar2(30000);
        l_header            varchar2(30000);
        l_payload           varchar2(30000);
        l_signature         varchar2(30000);
        l_secretkey         varchar2(10000):="your-secret-key";

        l_content           varchar2(30000);
        l_pay_clean         varchar2(30000);
        l_hdr_clean         varchar2(30000);

        l_header_base64     raw(30000);
        l_payload_base64    raw(30000);
        l_signature_base64  raw(30000);

    begin


        -- maak header middels json en base64 encode
        select json_object ('alg'  value 'HS256'
                           ,'typ'  value 'JWT')
        into   l_header
        from dual;

        -- maak payload middels json en base64 encode
        select json_object ('context' value
                    json_object ('user' value
                         json_object ('name' value p_naam))
                           ,'sub'  value 'text'
                           ,'iss'  value 'text'
                           ,'room' value '*'
                           ,'aud'  value 'jitsi')
        into   l_payload
        from dual;

        --
        l_header_base64  := utl_encode.base64_encode (utl_i18n.string_to_raw (l_header,  CONVERT_CHARSET));
        l_payload_base64 := utl_encode.base64_encode (utl_i18n.string_to_raw (l_payload, CONVERT_CHARSET));

        l_hdr_clean := cleanup_base64 (l_header_base64);
        l_pay_clean := cleanup_base64 (l_payload_base64);

        l_content := l_hdr_clean || '.' ||l_pay_clean;

        l_signature_base64  := utl_encode.base64_encode
                                      (dbms_crypto.mac(utl_i18n.string_to_raw (l_content, CONVERT_CHARSET)
                                                      ,dbms_crypto.hmac_sh256
                                                      ,utl_i18n.string_to_raw(l_secretkey, CONVERT_CHARSET)));

        l_signature :=  cleanup_base64 (l_signature_base64);
        l_token := l_hdr_clean||'.'||l_pay_clean||'.'|| l_signature;


        return l_token;
    end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 2018-10-05
    • 1970-01-01
    • 2019-05-19
    • 2017-04-16
    相关资源
    最近更新 更多