DPoP

DPoP (Demonstration of Proof-of-Possession)

**DPoP (Demostración de prueba de posesión) **es una extensión de OAuth 2.0 que garantiza que los tokens (acceso) estén vinculados al par de claves TPP (proveedor externo). Esto significa que incluso si se filtra un token, no se puede utilizar sin el correspondiente TPP privado generado aleatoriamente, evitando así ataques de repetición y uso indebido.

Paso 1: Genere un nuevo par de claves de firma usando OpenSSL

De acuerdo con el estándar DPoP, se recomienda utilizar llaves aleatorias en este paso.

  1. Elija un algoritmo (RSA PS256).
  2. Generar un nuevo par de claves aleatorias (clave privada y clave pública).

Paso 2: Convertir la clave pública al formato JWK

  1. DPoP requiere que la clave pública se incluya en el encabezado JWT como JWK (clave web JSON)
  2. Convierta su clave pública en formato PEM al formato JWK

Paso 3: Construir el DPoP JWT para la solicitud de token

  • El DPoP JWT consta de un header y una payload:
    • Header: Indica el tipo "dpop+jwt", el algoritmo "PS256" e incorpora su clave pública como JWK.
    • Payload: Contiene el método HTTP (htm), el URI HTTP (htu), la hora de emisión (iat) y un identificador único (jti).
  • Firmará este JWT con su clave privada generada en el Paso 1.

Headers

ParámetroValor de muestraDescripción
typdpop+jwtTipo de ficha
algPS256Algoritmo utilizado para firmar el JWT
jwk{##public key##}Clave pública en formato jwk.

Payload:

ParámetroValor de muestraDescripción
htmPOSTEl método HTTP que se utilizará para la API
htuhttps://api.stage.redebanopenfinance.com/51/token.oauth2/v1El endpoint de URL para la API
iat1758265669"Emitida en" marca de tiempo
jtilWkuS2iKLOebdS2nUn identificador único para el token.

Paso 4: Solicite un token de acceso

Solicitar endpoint de token con DPoP JWT creado con el valor del encabezado HTTP DPoP.


Ejemplo Curl para el Token

curl --location 'https://api.stage.redebanopenfinance.com/51/token.oauth2/v1' \
--key ./{network.key} \ 
--cert ./{network.pem} \
--header 'DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IlBTMjU2IiwiandrIjp7Imt0eSI6IlJTQSIsIng1dCNTMjU2IjoiQkNiamg3clZpTHZHczhqODZYbDRtWHNpQlJKT1U2UGZUM21xZ3FyeXRBRSIsIm5iZiI6MTczMTQxOTQ3NywiZSI6IkFRQUIiLCJ1c2UiOiJzaWciLCJraWQiOiJyc2Ffa2V5IiwieDVjIjpbIk1JSURnRENDQW1pZ0F3SUJBZ0lHQVpNZ3BKZWFNQTBHQ1NxR1NJYjNEUUVCQlFVQU1Id3hEakFNQmdOVkJBTU1CVVpzZFdabU1SSXdFQVlEVlFRTERBbERZWFFnU0c5MWMyVXhIREFhQmdOVkJBb01FME5oYldKeWFXUm5aU0JWYm1sMlpYSnpkSGt4RWpBUUJnTlZCQWNNQ1VOaGJXSnlhV1JuWlRFWE1CVUdBMVVFQ0F3T1EyRnRZbkpwWkdkbGMyaHBjbVV4Q3pBSkJnTlZCQVlUQWtkQ01CNFhEVEkwTVRFeE1qRXpOVEV4TjFvWERUTTBNVEV4TURFek5URXhOMW93ZFRFT01Bd0dBMVVFQXd3RlIybHVaMlV4RXpBUkJnTlZCQXNNQ2tSdlp5QkxaVzV1Wld3eEdqQVlCZ05WQkFvTUVVOTRabTl5WkNCVmJtbDJaWEp6YVhSNU1ROHdEUVlEVlFRSERBWlBlR1p2Y21ReEZEQVNCZ05WQkFnTUMwOTRabTl5WkhOb2FYSmxNUXN3Q1FZRFZRUUdFd0pIUWpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTHh0NFlNYWxLRnFxQ3ZobGRtK0FuWWJrMlRjOHZyVzdUazg2bHpJaHN3YXk4WGpwRWN5NTJpWHcvVWpYN01wZ2Nsc2RQKytjY3VTR2VhelpqZFBtblIxQXdhY0NWNm5JbklmeDJTTkhWMXhGV1d5cWZYR0JGN2ZibHZCMTJMWnVLeXRCK28yWFJ4UkI1elRkWE16c2NrSHp0Q0hoUm9ENzRoSmgwUjdMQTRXZ1VjU3FETjQ1d1d0NGZEdTdQR1hGbDN3b0lYT0pZYkpHVGN0RU0yaHorUElFNmRONlR3Y3FqczhXL0lBVmN6dmxVblpXbVNnejh5S05YWWN4TCtnRGlvdk5EY3ZsdVpiMjBoYzVSeHhDNmMzVUlCMTJDUGQxb1ErK1VWVjRsWGowSWdsUWs1Mzd3bE1WQTYyNUJuby9FeC9ZaVh1aW9zaVVyTHVJMk4rSmhNQ0F3RUFBYU1QTUEwd0N3WURWUjBQQkFRREFnZUFNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUJONHc1dmJoZmpTZUFiZHNNbjY1UkVGRHFwQmV1WEFidXRCUWJSeFpzSkZEekhSZkxkUUNUcGpRT0FSWWxQZkNwWnVCRVpuS2lsWldoQmVPd1pLcXlwQTB3aXpjTE5oVEgvUXBPdCt2ZzFoQnJ5M0RSWGlibnRDSDY4TnlLZmVNNS9uTVBRdWpKeS9QUzFwb2crR25zNnFpbU5GN1pKeHRvY0pLaWJiNHkyaG5uK1NDZHpTSkJRYnE4UTB2alZZQkhlU2lDMGZ2TDRxYkJNZmQ3QWhzbm5wQ3lyMUNHM1ZTTy8vTXFUQjUvMTJ3NlBnTnlIWjZScjNpZjEwNFpPWnA3UzVFcGgyRGVzRERtVENnL3E5NWJLcnpNSHJrSURtQkVKZ25jQ05WSTdxUXVueTJpZDI2VERCTFNsWEw4WTd2NHZ3Y3hqcmdjTEthV0ZFVW9wekRwTyJdLCJleHAiOjIwNDY3Nzk0NzcsIm4iOiJ2RzNoZ3hxVW9XcW9LLUdWMmI0Q2RodVRaTnp5LXRidE9UenFYTWlHekJyTHhlT2tSekxuYUpmRDlTTmZzeW1CeVd4MF83NXh5NUlaNXJObU4wLWFkSFVEQnB3SlhxY2ljaF9IWkkwZFhYRVZaYktwOWNZRVh0OXVXOEhYWXRtNHJLMEg2alpkSEZFSG5OTjFjek94eVFmTzBJZUZHZ1B2aUVtSFJIc3NEaGFCUnhLb00zam5CYTNoOE83czhaY1dYZkNnaGM0bGhza1pOeTBRemFIUDQ4Z1RwMDNwUEJ5cU96eGI4Z0JWek8tVlNkbGFaS0RQeklvMWRoekV2NkFPS2k4ME55LVc1bHZiU0Z6bEhIRUxwemRRZ0hYWUk5M1doRDc1UlZYaVZlUFFpQ1ZDVG5mdkNVeFVEcmJrR2VqOFRIOWlKZTZLaXlKU3N1NGpZMzRtRXcifX0.eyJodG0iOiJQT1NUIiwiaHR1IjoiaHR0cHM6Ly9hcGkuc3RhZ2UucmVkZWJhbm9wZW5maW5hbmNlLmNvbS81MS90b2tlbi5vYXV0aDIvdjEiLCJpYXQiOjE3NTgyNjU2NjksImp0aSI6ImxXa3VTMmlLTE9lYmRTMm4ifQ.LNmAI-Joc7qmkIcTy0uzCozinDdR_IYCiBxT59QFF_9sUKxg-IYOdCt0La6TV2DXN9jn17TiThBG0VvBxOLXEnrr_XeyBbOrDMVwETUTnG5Dvrkd_ESmRi_g-rIpSFhwkRK1CC5FUA9Zh7lxGc7yEsGqPnymmA8INyFoXM2tOdaw_MK_Mwwq8ZtlQtAQDPF617Wrm2t03uYxDSO6Fy8yjfwzon4hTHjbOKeDIbv5nbU-jGXp3zWgP60ETmVKRuKV-RGAPdPYlNHaARrjMVLegE5GpaO15mCnDpEAJAmQzAmg1lkOqjWLxpkwKzr7ePZel5ZU30Rt3Wjz1vxEi3lCHQ' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=SC-15e55bf8-be49-4e31-a12d-65acd396c337' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6Ijc2OEtSRWJUanRjckh2ZDdxcng3VjZsWU5YST0ifQ.eyJqdGkiOiJteUpXVElkMDAxIiwic3ViIjoiU0MtMTVlNTViZjgtYmU0OS00ZTMxLWExMmQtNjVhY2QzOTZjMzM3IiwiaXNzIjoiU0MtMTVlNTViZjgtYmU0OS00ZTMxLWExMmQtNjVhY2QzOTZjMzM3IiwiYXVkIjoiaHR0cHM6Ly9hdXRoLnN0YWdlLnJlZGViYW5vcGVuZmluYW5jZS5jb20iLCJpYXQiOjE3MzQ2OTQxMzksImV4cCI6MTc2NzE4NTgyNn0.NjwSF-_8nuc-BRp29ZPqYPcrtvAZdCF8GJkJNDPhJMbeDz3Va0O3GJvFj1LOQwRqcz8IYQUeRcKuPlzaLNwjz4hwhau-x6evArlQ4pkx_nvUmiKEmh4hPzRkgaJMRWyI56KgDL9cOk-0RS2ucAEUBuwWKSbSASuMo1hQnEjd-sL0VZEk7Ulier0TLBOE20KEW17Z-Ira5HrkHBZNgBEaBbKth6sntZD34BOiVB6SpDM-Tg2KjQBLLGCwXq44EfT9FtHhostmGQ3ovzZvxsgYwsW6U_mLBi9xJLDBELAtTCSR7s1S5Ae-X3OLfunB4-iBmcNtvmIrB0Cz7Sz_51bptA' \
--data-urlencode 'scope=payments'

Paso 5: Prepárese para el acceso a los recursos

  • Para acceder a los recursos, necesita crear otro DPoP JWT que consta de un header y una payload:
    • Header: Indica el tipo "dpop+jwt", el algoritmo "PS256" e incorpora su clave pública como JWK. (igual que el paso 3)
    • Payload: Contiene el método HTTP (htm), el URI HTTP (htu), el momento de emisión (iat) y un identificador único (jti), y el claim ath (ath), que es un hash (SHA-256, codificado en base64url) de su token de acceso.
  • Firme este JWT con la misma clave privada de firma generada en el paso 1.

Headers

ParámetroValor de muestraDescripción
typdpop+jwtTipo de ficha
algPS256Algoritmo utilizado para firmar el JWT
jwkpublic key valueClave pública en formato jwk

Payload:

ParámetroValor de muestraDescripción
htmPOSTEl método HTTP que se utilizará para la API
htuhttps://api.stage.redebanopenfinance.com/51/back-channel-auth/v1/5061316a-3f1e-413e-ad43-3db94d773f93El endpoint de URL para la API
athCXGXnOFRmKh9Tnvf6tHrSHiUMHrJwAR4h0eRyIe-poMun hash (SHA-256, codificado en base64url) del token de acceso
iat1758266744,"Emitida en" marca de tiempo
jtii-UVxK6hqsjrscpiUn identificador único para el token.

Paso 6: acceda a la API protegida

  • Enviar una solicitud HTTP POST al endpoint del recurso protegido API de Consentimiento de pago, Pago nacional y Confirmación de fondos.
  • Incluir el token de acceso en el encabezado de Autorización, utilizando el esquema "DPoP".
  • Incluya su nuevo DPoP JWT en el encabezado DPoP.
  • El servidor validará su prueba de posesión y, si todo es correcto, le dará acceso al recurso.

Ejemplo Curl para Consentimiento (Payment Consent)

curl --location 'https://api.stage.redebanopenfinance.com/51/domestic-payment-consents/v1' \
--key ./{network.key} \ 
--cert ./{network.pem} \
--header 'Content-Type: application/json' \
--header 'Authorization: DPoP v72Z3xciL8ZTInNTqZiJ43PI1QwMFeFka3NRfbnam5A' \
--header 'x-idempotency-key: 2' \
--header 'x-jws-signature: eyJhbGciOiJQUzI1NiIsInR5cCI6IkpPU0UiLCJjcml0IjpbImh0dHA6Ly9vcGVuYmFua2luZy5vcmcudWsvaWF0IiwiaHR0cDovL29wZW5iYW5raW5nLm9yZy51ay9pc3MiLCJodHRwOi8vb3BlbmJhbmtpbmcub3JnLnVrL3RhbiJdLCJodHRwOi8vb3BlbmJhbmtpbmcub3JnLnVrL2lzcyI6Ik9CLWU1ZjU4YWNlLTA5NjEtNGU0NC1hZjNjLTM1MjY1ZWQ4YjdjOS9TQy0xNWU1NWJmOC1iZTQ5LTRlMzEtYTEyZC02NWFjZDM5NmMzMzciLCJodHRwOi8vb3BlbmJhbmtpbmcub3JnLnVrL2lhdCI6MTc1MDA1ODc1NiwiaHR0cDovL29wZW5iYW5raW5nLm9yZy51ay90YW4iOiJvcGVuYmFua2luZy5vcmcudWsiLCJraWQiOiI3NjhLUkViVGp0Y3JIdmQ3cXJ4N1Y2bFlOWEk9IiwiY3R5IjoiYXBwbGljYXRpb24vanNvbiJ9..Bp_YLjqGUTtQNCcHDpNMsw8YJ2Q4F5TAifC78U8Nvd1LuDzHtOsH6DEIbyvkt_6dcV-sTu9_IYh7-mOA2v4CLY_fzz7PSLCgcys3yMjPEJSITz6V63iUh-Ujpo6-Ry9RTrptV5JdZ7SaW8u-rNClMROi4Inii6VLA8XFxJihkI7pzQfSPyt_jJGkaOyZd0MzgpGKW30HmWCQ2VNdieuMwydPeWdKKTMFTqDSMCs1QdFSOaKKVs9OK5oEBtGTrCwb5X-OgZ2O42lfK6hveXnbEB4YaDbxgVc_Y2Zzut7QrpkwpdouJnH8A9Fag2hh_vIxHv1SUuxVrd2MPZwWwziJlw' \
--header 'DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IlBTMjU2IiwiandrIjp7Imt0eSI6IlJTQSIsIng1dCNTMjU2IjoiQkNiamg3clZpTHZHczhqODZYbDRtWHNpQlJKT1U2UGZUM21xZ3FyeXRBRSIsIm5iZiI6MTczMTQxOTQ3NywiZSI6IkFRQUIiLCJ1c2UiOiJzaWciLCJraWQiOiJyc2Ffa2V5IiwieDVjIjpbIk1JSURnRENDQW1pZ0F3SUJBZ0lHQVpNZ3BKZWFNQTBHQ1NxR1NJYjNEUUVCQlFVQU1Id3hEakFNQmdOVkJBTU1CVVpzZFdabU1SSXdFQVlEVlFRTERBbERZWFFnU0c5MWMyVXhIREFhQmdOVkJBb01FME5oYldKeWFXUm5aU0JWYm1sMlpYSnpkSGt4RWpBUUJnTlZCQWNNQ1VOaGJXSnlhV1JuWlRFWE1CVUdBMVVFQ0F3T1EyRnRZbkpwWkdkbGMyaHBjbVV4Q3pBSkJnTlZCQVlUQWtkQ01CNFhEVEkwTVRFeE1qRXpOVEV4TjFvWERUTTBNVEV4TURFek5URXhOMW93ZFRFT01Bd0dBMVVFQXd3RlIybHVaMlV4RXpBUkJnTlZCQXNNQ2tSdlp5QkxaVzV1Wld3eEdqQVlCZ05WQkFvTUVVOTRabTl5WkNCVmJtbDJaWEp6YVhSNU1ROHdEUVlEVlFRSERBWlBlR1p2Y21ReEZEQVNCZ05WQkFnTUMwOTRabTl5WkhOb2FYSmxNUXN3Q1FZRFZRUUdFd0pIUWpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTHh0NFlNYWxLRnFxQ3ZobGRtK0FuWWJrMlRjOHZyVzdUazg2bHpJaHN3YXk4WGpwRWN5NTJpWHcvVWpYN01wZ2Nsc2RQKytjY3VTR2VhelpqZFBtblIxQXdhY0NWNm5JbklmeDJTTkhWMXhGV1d5cWZYR0JGN2ZibHZCMTJMWnVLeXRCK28yWFJ4UkI1elRkWE16c2NrSHp0Q0hoUm9ENzRoSmgwUjdMQTRXZ1VjU3FETjQ1d1d0NGZEdTdQR1hGbDN3b0lYT0pZYkpHVGN0RU0yaHorUElFNmRONlR3Y3FqczhXL0lBVmN6dmxVblpXbVNnejh5S05YWWN4TCtnRGlvdk5EY3ZsdVpiMjBoYzVSeHhDNmMzVUlCMTJDUGQxb1ErK1VWVjRsWGowSWdsUWs1Mzd3bE1WQTYyNUJuby9FeC9ZaVh1aW9zaVVyTHVJMk4rSmhNQ0F3RUFBYU1QTUEwd0N3WURWUjBQQkFRREFnZUFNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUJONHc1dmJoZmpTZUFiZHNNbjY1UkVGRHFwQmV1WEFidXRCUWJSeFpzSkZEekhSZkxkUUNUcGpRT0FSWWxQZkNwWnVCRVpuS2lsWldoQmVPd1pLcXlwQTB3aXpjTE5oVEgvUXBPdCt2ZzFoQnJ5M0RSWGlibnRDSDY4TnlLZmVNNS9uTVBRdWpKeS9QUzFwb2crR25zNnFpbU5GN1pKeHRvY0pLaWJiNHkyaG5uK1NDZHpTSkJRYnE4UTB2alZZQkhlU2lDMGZ2TDRxYkJNZmQ3QWhzbm5wQ3lyMUNHM1ZTTy8vTXFUQjUvMTJ3NlBnTnlIWjZScjNpZjEwNFpPWnA3UzVFcGgyRGVzRERtVENnL3E5NWJLcnpNSHJrSURtQkVKZ25jQ05WSTdxUXVueTJpZDI2VERCTFNsWEw4WTd2NHZ3Y3hqcmdjTEthV0ZFVW9wekRwTyJdLCJleHAiOjIwNDY3Nzk0NzcsIm4iOiJ2RzNoZ3hxVW9XcW9LLUdWMmI0Q2RodVRaTnp5LXRidE9UenFYTWlHekJyTHhlT2tSekxuYUpmRDlTTmZzeW1CeVd4MF83NXh5NUlaNXJObU4wLWFkSFVEQnB3SlhxY2ljaF9IWkkwZFhYRVZaYktwOWNZRVh0OXVXOEhYWXRtNHJLMEg2alpkSEZFSG5OTjFjek94eVFmTzBJZUZHZ1B2aUVtSFJIc3NEaGFCUnhLb00zam5CYTNoOE83czhaY1dYZkNnaGM0bGhza1pOeTBRemFIUDQ4Z1RwMDNwUEJ5cU96eGI4Z0JWek8tVlNkbGFaS0RQeklvMWRoekV2NkFPS2k4ME55LVc1bHZiU0Z6bEhIRUxwemRRZ0hYWUk5M1doRDc1UlZYaVZlUFFpQ1ZDVG5mdkNVeFVEcmJrR2VqOFRIOWlKZTZLaXlKU3N1NGpZMzRtRXcifX0.eyJodG0iOiJQT1NUIiwiaHR1IjoiaHR0cHM6Ly9hcGkuc3RhZ2UucmVkZWJhbm9wZW5maW5hbmNlLmNvbS81MS9iYWNrLWNoYW5uZWwtYXV0aC92MS81MDYxMzE2YS0zZjFlLTQxM2UtYWQ0My0zZGI5NGQ3NzNmOTMiLCJhdGgiOiJDWEdYbk9GUm1LaDlUbnZmNnRIclNIaVVNSHJKd0FSNGgwZVJ5SWUtcG9NIiwiaWF0IjoxNzU4MjY2NzQ0LCJqdGkiOiJpLVVWeEs2aHFzanJzY3BpIn0.ffRRH1urJob1o0AaXNH3S1Cr23LrpCAena0LsKRtIjw6lBZWA5mmL5laqWq1I7sPNtS2kXljHEqcHQP0rJCqYf0vznw7Ygh0BZucvqoZyIfdSdkPvLsGAe7mio5yoj4Jcl-OfnRX8Ek11vsBq22peK0x3PK5zfRDOLukAyxa1aRY6_SjCEB1yTSCwQXCRbyxztfuyu3WUofoKXcTNQbFW1Iq-k1_8T6c_aDvOd-8YfeTMEwNST9mmeJgZa_P1_X_eKsE64p0Kyv1L-BJUQukn-yFWbOty9PL0wOaJA6OpjzK2pINw4b9w1kIIgWIrWKvl5FpFCoxyEVBWx1bxJUB3A' \
--data '{"Data":{"ReadRefundAccount":"Yes","Authorisation":{"AuthorisationType":"Any","CompletionDateTime":"2025-11-12T00:00:00+00:00"},"Initiation":{"InstructionIdentification":"0555ca8f-bca6-470e-a192-2e897578a30","EndToEndIdentification":"DEMO USER","InstructedAmount":{"Amount":"115.00","Currency":"COP"},"CreditorAccount":{"SchemeName":"CAHO","Identification":"0036024594","Name":"Test user","SecondaryIdentification":"MERCHANTID"},"DebtorAccount":{"SchemeName":"CAHO","Identification":"3559898989","Name":"JESSICA","SecondaryIdentification":"1001017"},"CreditorPostalAddress":{"AddressLine":["test"],"AddressType":"Business","BuildingNumber":"27","Country":"GB","CountrySubDivision":"Wessex","Department":"test","PostCode":"7U31 2ZZ","StreetName":"AcaciaAvenue","SubDepartment":"test sub","TownName":"Sparsholt"},"SupplementaryData":{"DebtorMobileNumber":"3138745276"},"RemittanceInformation":{"Unstructured":"Internal ops code 5120101","Reference":"FRESCO-101"}},"SCASupportData":{"RequestedSCAExemptionType":"BillPayment","AppliedAuthenticationApproach":"CA","ReferencePaymentOrderId":"test"}},"Risk":{"PaymentContextCode":"Other","MerchantCategoryCode":"5967","MerchantCustomerIdentification":"053598653254","DeliveryAddress":{"AddressLine":["Flat 7","Acacia Lodge"],"StreetName":"AcaciaAvenue","BuildingNumber":"27","PostCode":"7U31 2ZZ","TownName":"Sparsholt","CountrySubDivision":"Wessex","Country":"GB"}}}'



Consulte el estándar definido en https://datatracker.ietf.org/doc/html/rfc9449 .

© Redeban. Reservados todos los derechos