Skip to main content

Authentication - CSR/JWT (test)

Which products require this?

This authentication method is used for the following products:

  • Payment API
  • Balance API
  • Statement API
  • qvik EAM
  • Payment Request

The Online Payment Page uses HMAC-based authentication → HMAC authentication


Creating the Configuration File​

Using the test registration number provided by the bank, the configuration file must be created according to the following template. The string at the end of the highlighted line (27.) (example: AB1234) must be replaced with the test registration number.

Good to know

Please make sure there is no space between the test registration number and the colon!

csr_details_minta_v02.txt
oid_section = oids

[req ]
default_bits = 2048
prompt = no
default_md = sha512
distinguished_name = dn
req_extensions = req_ext

[ oids ]
apiUserType = 1.2.3.45

[ dn ]
C=HU
ST= Budapest
L= Budapest
O=APIUser
OU=APIUser_OU
emailAddress=admin@yourdomain.com
CN = apiuser@yourdomain.com

[ req_ext ]
subjectAltName = @alt_names
basicConstraints = critical, CA:FALSE
keyUsage = digitalSignature, keyEncipherment
apiUserType = ASN1:UTF8String:PaymentHUB
2.5.4.97 = ASN1:UTF8String:AB1234

[ alt_names ]
DNS.1 = yourdomain.com

Generating the Private Key and CSR File​

Creating the private-public key pair and the certificate signing request (CSR) file required for signing the authentication token is essential.

Using the configuration file produced above, the private key and CSR file must be generated using openssl, following the template below:

openssl genrsa -out key.pem 2048
openssl req -new -key key.pem -out csr.pem -config csr_details.txt

Result:

  • key.pem - Private key (for signing JWT token)
  • csr.pem - Certificate Signing Request (to be uploaded to RPP)

Generating KID and Uploading the Certificate​

1. Uploading CSR to RPP​

On the Certificates tab, click the Upload New Certificate Request button.

Upload new certificate request

Select the CSR file generated in the previous step (csr.pem), upload it and give it a name.

Select CSR file Rename CSR file

2. Extracting KID and Credentials​

After this, the necessary information can be extracted from the RPP portal interface:

  • Technical User ID
  • x-api-key (API key)
  • KID (Key ID) - to be used in JWT token header
Extract information
Using KID

The KID (Key ID) value must be used in the kid header field when generating JWT tokens.


Signature structure

The Detached JWS consists of three main components: Header, Payload and Signature. These are detailed below.


1. Header​

The header contains the metadata required for signature validation. The header must be composed in JSON format and then Base64URL encoded.

Required fields​

FieldTypeDescription
kidstringKey ID - The unique identifier belonging to the certificate. Can be obtained from the RaiffeisenPay Portal.
typstringToken type - always "JWT"
algstringSigning algorithm - "RS512" (RSA-SHA512)
iatintegerIssued At - Unix timestamp in seconds (time of signing)
jtistringJWT ID - Unique identifier (UUID v4). A new value must be generated for each API call!

Header template​

{
"kid": "<KID value from the RaiffeisenPay Portal>",
"typ": "JWT",
"alg": "RS512",
"iat": <unix_timestamp>,
"jti": "<uuid_v4>"
}

Header example​

{
"kid": "/SN=15349700155842404063/C=HU/L=Budapest/OU=only_for_development_use/CN=p19026_openbanking_-_api_user_certificates",
"typ": "JWT",
"alg": "RS512",
"iat": 1585563716,
"jti": "e395cf5e-0fc4-430b-9f7e-bee20855b475"
}

:::tip KID value The kid value can be obtained from the RaiffeisenPay Portal after uploading the certificate. :::


2. Payload​

The payload is the HTTP request body in JSON format. This is the data you sign and send to the server.

:::danger Critical: Formatting consistency The JWS signature is unique to the given header and payload combination. The JSON sent in the HTTP body MUST EXACTLY match the signed payload.

Many JWT libraries remove whitespace and line breaks before signing. If the formatting of the sent body differs from the signed one, the API will reject the request.

Solution: Use the same JSON string for both signing and sending as the HTTP body. :::

Payload example​

{
"orderID": "order_123456",
"creditorAccount": "HU96120106590163520000100000",
"transactionAmount": 1000,
"transactionCurrency": "HUF"
}

3. Signature​

The signature is the cryptographic fingerprint of the header and payload combination, created with your private key.

Troubleshooting​

JWT error codes​

Error codeProblemSolution
JWT_GENERAL_ERRORIncorrect JWT assembly or body/payload mismatchCheck that the HTTP body exactly matches the signed payload
JWT_CERT_EXPIREDExpired certificateGenerate and activate a new certificate on the RPP portal
JWT_CERT_NOT_ACTIVECertificate not activatedActivate the certificate on the RPP portal
JWT_IAT_EXPIREDThe iat timestamp is too old or in the futureUse accurate current system time
JWT_JTI_DUPLICATEThe same jti value used twiceGenerate a new UUID for each call
JWT_NOT_EXISTSMissing x-jws-signature headerAdd the Detached JWT to the header

Common errors​

ErrorCauseSolution
401 UnauthorizedIncorrect JWS signatureCheck the JWS generation and that the body matches the signed payload
401 UnauthorizedWrong KIDCheck that you are using the correct KID
401 UnauthorizedExpired certificateGenerate and upload new CSR
Invalid signatureWrong private keyCheck that you are using the private key belonging to the CSR

Next Steps​

Payment API and Balance API users

After CSR setup and KID extraction, Consent creation and approval is still required on the RPP portal.

Consent management →

EAM and Payment Request users

With the KID in hand, you can now make your first API call.

First API call →