如何计算PCKE的code_verifier? [英] How to calculate PCKE's code_verifier?

查看:77
本文介绍了如何计算PCKE的code_verifier?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过

使用 Zg6klgrnixQJ629GsawRMV8MjWvwRAr-vyvP1MHnB6X8WKZN 作为代码验证程序,它们是如何产生的
iF_7prUeJ6rr3jMG3LmhW3R1cZ2ecZavFqS0jtb6tzo 是代码挑战吗?

使用此 SHA256哈希计算器 Base64的编码器的,我<代码> ODg1ZmZiYTZiNTFlMjdhYWViZGUzMzA2ZGNiOWExNWI3NDc1NzE5ZDllNzE5NmFmMTZhNGI0OGVkNmZhYjczYQ 不匹配的<代码> iF_7prUeJ6rr3jMG3LmhW3R1cZ2ecZavFqS0jtb6tzo 的预期值.我无法获得期望的值在做什么呢?

这个 approsto的SHA256 base 64哈希计算器给我提供了一个非常接近期望值的值价值.使用此计算器,我得到 iF/7prUeJ6rr3jMG3LmhW3R1cZ2ecZavFqS0jtb6tzo ,它与期望值相差一个字符(注意,如何用/代替 _ .).

我正在做什么导致这种差异?如何计算 iF_7prUeJ6rr3jMG3LmhW3R1cZ2ecZavFqS0jtb6tzo 的预期 code_verifier 值?谢谢

解决方案

PKCE代码挑战是验证程序的Base64-URL编码的SHA256哈希.这意味着您需要获取原始字符串,计算它的SHA256哈希值,然后对哈希值进行Base64-URL编码.这是很多话,所以让我们来看一下.

您上面尝试执行的操作有两个问题:

您找到的在线SHA256哈希计算器将哈希输出为十六进制编码的字符串,而不是原始字节.这通常很有帮助,但在这种情况下没有帮助.因此,通过base64编码要做的下一件事是,您正在对base64编码哈希的十六进制表示形式而不是原始字节进行编码.您需要使用散列函数输出原始字节,并将原始字节传递到base64-url-encoder.

下一个问题是您需要base64-url编码,而不是base64编码.Base64-URL-encoding是Base64编码的一个较小变体,唯一的区别是使用字符-代替了 + _ /,并从末尾修剪 = 填充字符.这使它成为URL安全的,因为否则将需要在URL中转义 +/= 字符.

因此,要计算PKCE代码挑战,您需要使用可以为您提供原始字节的SHA256函数,然后使用经过修改的Base64编码函数对这些字节进行编码.

以下是PHP中的一些代码可以做到这一点:

 函数pkce_code_challenge($ verifier){$ hash = hash('sha256',$ verifier,true);返回rtrim(strtr(base64_encode($ hash),'+/','-_'),'=');} 

在浏览器中使用纯JavaScript也可以,但是由于WebCrypto API的复杂性,代码会稍长一些:

 函数sha256(plain){//返回promise ArrayBufferconst encoder = new TextEncoder();const data = encoder.encode(plain);返回window.crypto.subtle.digest('SHA-256',数据);}函数base64urlencode(a){//使用Uint8数组将ArrayBuffer转换为字符串.//btoa接受0-255之间的char和base64编码.//然后将base64编码转换为base64url编码.//(用-替换+,用_替换/,尾随修剪=)返回btoa(String.fromCharCode.apply(null,新的Uint8Array(a))).replace(/\ +/g,'-').replace(/\//g,'_').replace(/= + $/,'');}异步函数pkce_challenge_from_verifier(v){散列=等待sha256(v);base64encoded = base64urlencode(hashed);返回base64encoded;} 

I'm going through Okta's PCKE Flow demo to get a better understanding of how it works, and I'm having trouble reproducing the same code_challenge hash that's being generated from the code_verifier. Here's a screenshot of the demo:

Using Zg6klgrnixQJ629GsawRMV8MjWvwRAr-vyvP1MHnB6X8WKZN as the code verifier, how did they produce
iF_7prUeJ6rr3jMG3LmhW3R1cZ2ecZavFqS0jtb6tzo as the code challenge?

Using this SHA256 hash calculator and Base64 Encoder, I got ODg1ZmZiYTZiNTFlMjdhYWViZGUzMzA2ZGNiOWExNWI3NDc1NzE5ZDllNzE5NmFmMTZhNGI0OGVkNmZhYjczYQ which doesn't match the expected value of iF_7prUeJ6rr3jMG3LmhW3R1cZ2ecZavFqS0jtb6tzo. What am I doing wrong to not get the expected value?

This SHA256 base 64 hash calculator from approsto gives me a value that is very close to the expected value. Using this calculator I get iF/7prUeJ6rr3jMG3LmhW3R1cZ2ecZavFqS0jtb6tzo which is one character off from the expected value (notice how there's a / instead of _).

What am I doing that's causing this discrepancy? How do I calculate the expected code_verifier value of iF_7prUeJ6rr3jMG3LmhW3R1cZ2ecZavFqS0jtb6tzo? Thanks

解决方案

The PKCE code challenge is the Base64-URL-encoded SHA256 hash of the verifier. This means you need to take the original string, calculate the SHA256 hash of it, then Base64-URL-encode the hash. That's a lot of words, so let's walk through it.

There are two problems with what you've tried to do above:

The online SHA256 hash calculator you found outputs the hash as a hex-encoded string rather than the raw bytes. That's typically helpful, but in this case is not. So the next thing you're doing by base64 encoding is that you're base64 encoding the hex representation of the hash rather than the raw bytes. You need to use a hash function that outputs the raw bytes, and pass the raw bytes into the base64-url-encoder.

The next problem is that you need to base64-url encode, not base64 encode. Base64-URL-encoding is a minor variation of Base64 encoding, where the only difference is using the character - instead of + and _ instead of /, and trimming the = padding characters from the end. This makes it URL-safe, since otherwise the +/= characters would need to be escaped in the URL.

So, to calculate the PKCE code challenge, you need to use a SHA256 function that can give you the raw bytes, then use a modified Base64 encoding function to encode those bytes.

Here is some code in PHP that will do that:



    function pkce_code_challenge($verifier) {
        $hash = hash('sha256', $verifier, true);
        return rtrim(strtr(base64_encode($hash), '+/', '-_'), '=');
    }

It's also possible in plain JavaScript in a browser, but the code is slightly longer due to the complexity of the WebCrypto APIs:



    function sha256(plain) { 
        // returns promise ArrayBuffer
        const encoder = new TextEncoder();
        const data = encoder.encode(plain);
        return window.crypto.subtle.digest('SHA-256', data);
    }

    function base64urlencode(a) {
        // Convert the ArrayBuffer to string using Uint8 array.
        // btoa takes chars from 0-255 and base64 encodes.
        // Then convert the base64 encoded to base64url encoded.
        // (replace + with -, replace / with _, trim trailing =)
        return btoa(String.fromCharCode.apply(null, new Uint8Array(a)))
            .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
    }

    async function pkce_challenge_from_verifier(v) {
        hashed = await sha256(v);
        base64encoded = base64urlencode(hashed);
        return base64encoded;
    }

这篇关于如何计算PCKE的code_verifier?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆