Table of Contents
Puedes generar code_verifier y code_challenge para la autorización OIDC de la siguiente manera. Los siguientes códigos también están disponibles en Gist.
JavaScript
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// This code works on the Web Browser, because it uses Web Crypto API. const codeVerifierLength = 43; let codeVerifier = ''; const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'; for (let i = 0; i < codeVerifierLength; i++) { codeVerifier += characters.charAt(Math.floor(Math.random() * characters.length)); } async function generateCodeChallenge(codeVerifier) { let digest = await crypto.subtle.digest( "SHA-256", new TextEncoder().encode(codeVerifier) ); return btoa(String.fromCharCode(...new Uint8Array(digest))). replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); } const codeChallenge = await generateCodeChallenge(codeVerifier); console.log(`Code Verifier : ${codeVerifier}`); console.log(`Code Challenge: ${codeChallenge}`); |
F#
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
open System open System.Linq let codeVerifierLength = 43 let random = Random() let chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~" let codeVerifier = Enumerable.Repeat(chars, codeVerifierLength). Select(fun s -> s.[random.Next(s.Length)]) |> String.Concat let codeChallenge = codeVerifier |> System.Text.Encoding.UTF8.GetBytes |> System.Security.Cryptography.SHA256.Create().ComputeHash |> System.Convert.ToBase64String |> fun x -> x.Replace("=", "").Replace("+", "-").Replace("/", "_") printfn "Code Verifier : %s" codeVerifier printfn "Code Challenge: %s" codeChallenge |
Python
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import base64 import hashlib import random import string code_verifier_length = 43 code_verifier = ''.join(random.choice(string.ascii_letters + string.digits + '-._~')\ for i in range(code_verifier_length)) code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).\ decode().replace("=", "").replace("+", "-").replace("/", "_") print("Code Verifier :", code_verifier) print("Code Challenge:", code_challenge) |
Ruby
|
1 2 3 4 5 6 7 8 9 10 11 12 |
require 'digest' require 'base64' code_verifier_length = 43 o = ([('a'..'z'), ('A'..'Z'), ('0'..'9')].map(&:to_a) + %w[- _ . ~]).flatten code_verifier = (0...code_verifier_length).map { o[rand(o.length)] }.join code_challenge = Base64.urlsafe_encode64(Digest::SHA256.digest(code_verifier)). delete('=').gsub('+', '-').gsub('/', '_') puts "Code Verifier : #{code_verifier}" puts "Code Challenge: #{code_challenge}" |
Shell Script
|
1 2 3 4 5 6 7 |
CODE_VERIFIER_LENGTH=43 CODE_VERIFIER=`cat /dev/urandom | LC_CTYPE=C tr -dc 'a-zA-Z0-9\-._~' | fold -w $CODE_VERIFIER_LENGTH | head -n 1` CODE_CHALLENGE=`echo -n $CODE_VERIFIER | openssl dgst -sha256 -binary | openssl base64 -A | tr -d '=' | tr '/+' '_-'` echo "Code Verifier :" $CODE_VERIFIER echo "Code Challenge:" $CODE_CHALLENGE |
PKCE, Clave de Prueba para el Intercambio de Códigos
El verificador de código y el desafío de código son elementos que se utilizan en el mecanismo PKCE. PKCE es una mejora de seguridad para los flujos de autorización de OAuth 2.0 y OpenID Connect (OIDC). Se utiliza principalmente para protegerse contra los ataques de interceptación de código de autorización.
Así es como funciona.
Flujo de Código de Autorización
- En el flujo de código de autorización estándar de OAuth 2.0, una aplicación cliente solicita un código de autorización al servidor de autorización.
- El código de autorización luego se intercambia por un token de acceso.
- Sin embargo, este flujo es vulnerable a ataques de interceptación, especialmente en aplicaciones móviles o de una sola página.
PKCE al Rescate
- PKCE introduce un paso adicional antes de intercambiar el código de autorización por un token de acceso.
- El cliente genera un verificador de código aleatorio y calcula su valor hash (el desafío de código).
- El verificador de código se envía al servidor de autorización durante la solicitud de autorización inicial.
- El servidor almacena el desafío de código asociado con el código de autorización.
- Cuando el cliente intercambia el código de autorización por un token de acceso, también debe enviar el verificador de código original.
- El servidor verifica que el verificador de código coincida con el desafío de código almacenado.
¿Por qué es importante PKCE?
- PKCE evita que los atacantes intercepten el código de autorización y lo utilicen para obtener un token de acceso.
- Incluso si un atacante captura el código de autorización, no tendrán el verificador de código correspondiente.
- Esto hace que sea mucho más difícil realizar el robo de tokens.
Uso
- Se recomienda PKCE para todos los clientes públicos (por ejemplo, aplicaciones móviles, aplicaciones de una sola página) que utilizan el flujo de código de autorización.
- Los clientes confidenciales (por ejemplo, aplicaciones del lado del servidor) también pueden usar PKCE para una seguridad adicional.
Recuerde, PKCE es como un apretón de manos secreto entre su aplicación y el servidor de autorización, asegurando que solo el destinatario previsto pueda completar el proceso de autorización.

