authCode calculation

The authCode parameter is calculated using a sessionSecret value and added to the device links (QR/Web2App/App2App) in order to protect the link from unauthorized changes. Calculation of the authCode parameter also relies on the assembled device link itself (except for the authCode parameter). This assembled device link without the authCode parameter is referred to as unprotectedDeviceLink.

authCodePayload fields

The order of the fields in the authCodePayload must be the same as specified in the examples below.

All values are required and must be non-empty; the only exceptions to this are:

  • in QR flows, initialCallbackUrl must be empty and the separator must still be used, i.e. ||;

  • in same-device flows (App2App & Web2App), elapsedSeconds parameter must be missing from unprotectedDeviceLink.

  • in certificate-choice session requests parameters digest, interactions and signatureProtocol must be included as empty fields;

Encoding

Both Base64 and Base64URL encodings are used in the RP API, be careful to use the appropriate encoding as specified.

As specified in RFC 4648 Section 5, Base64URL makes the following two substitutions in comparison with the standard Base64 alphabet: +- and /_ and as allowed in RFC 4648 Section 3.2 all trailing = characters must be omitted.

However, it is recommended to use a standard library function for encoding Base64URL.

authCode parameter

As the first step, RP assembles authCodePayload using byte concatenation, using the byte representation of vertical bar character | (U+007C) as a separator:

  • Web2App

  • App2App

  • QR

  • Authentication Session

  • Signature Session

  • Certificate-choice Session

For authentication session device links signatureProtocol value is ACSP_V2:

authCodePayload := UTF8-ENCODE(STR-CONCAT(
        'smart-id', '|',
        'ACSP_V2', '|',
        rpChallenge, '|',
        BASE64-ENCODE(relyingPartyName), '|',
        BASE64-ENCODE(brokeredRpName), '|',
        interactions, '|',
        initialCallbackUrl, '|',
        unprotectedDeviceLink))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class AuthCodePayload {

  public static void main(String[] args) throws Exception {
    String separator = "|";
    String schemeName = "smart-id";
    String signatureProtocol = "ACSP_V2";
    String rpChallenge = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==";
    String relyingPartyNameBase64 = "REVNTw==";
    String brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
    String interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    String initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    String unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    String[] payloadParts = {
      schemeName,
      signatureProtocol,
      rpChallenge,
      relyingPartyNameBase64,
      brokeredRpNameBase64,
      interactions,
      initialCallbackUrl,
      unprotectedDeviceLink
    };

    String authCodePayload = String.join(separator, payloadParts);
    System.out.println(authCodePayload);
  }
}
<?php

$separator = '|';

$schemeName = 'smart-id';
$signatureProtocol = 'ACSP_V2';
$rpChallenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==';
$relyingPartyNameBase64 = 'REVNTw==';
$brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
$interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
$initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
$unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

$authCodePayload = implode($separator, [
    $schemeName,
    $signatureProtocol,
    $rpChallenge,
    $relyingPartyNameBase64,
    $brokeredRpNameBase64,
    $interactions,
    $initialCallbackUrl,
    $unprotectedDeviceLink
]);

echo $authCodePayload;

?>
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'ACSP_V2'
rp_challenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = separator.join([
    scheme_name,
    signature_protocol,
    rp_challenge,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
])

print(auth_code_payload)
package main

import (
	"fmt"
)

func main() {
	var separator string = "|"

	var schemeName string = "smart-id"
	var signatureProtocol string = "ACSP_V2"
	var rpChallenge string = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=="
	var relyingPartyNameBase64 string = "REVNTw=="
	var brokeredRpNameBase64 string = "RXhhbXBsZSBSUA=="
	var interactions string = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
	var initialCallbackUrl string = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
	var unprotectedDeviceLink string = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

	var payloadParts = []string{
		schemeName,
		signatureProtocol,
		rpChallenge,
		relyingPartyNameBase64,
		brokeredRpNameBase64,
		interactions,
		initialCallbackUrl,
		unprotectedDeviceLink,
	}

	var authCodePayload string = strings.Join(payloadParts, separator)

	fmt.Printf("%q\n", authCodePayload)
}
fn main() {
    let separator: &str = "|";
    let scheme_name: &str = "smart-id";
    let signature_protocol: &str = "ACSP_V2";
    let rp_challenge: &str = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==";
    let relying_party_name_base64: &str = "REVNTw==";
    let brokered_rp_name_base64: &str = "RXhhbXBsZSBSUA==";
    let interactions: &str = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    let initial_callback_url: &str = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    let unprotected_device_link: &str = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    let auth_code_payload_parts: [&str; 7] = [
        scheme_name,
        signature_protocol,
        rp_challenge,
        relying_party_name_base64,
        brokered_rp_name_base64,
        interactions,
        initial_callback_url,
        unprotected_device_link
    ];

    let auth_code_payload: String = auth_code_payload_parts.join(separator);

    println!("{}", auth_code_payload)
}
fun main() {
    val separator: String = "|"

    val schemeName: String = "smart-id"
    val signatureProtocol: String = "ACSP_V2"
    val rpChallenge: String = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=="
    val relyingPartyNameBase64: String = "REVNTw=="
    val brokeredRpNameBase64: String = "RXhhbXBsZSBSUA=="
    val interactions: String = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
    val initialCallbackUrl: String = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
    val unprotectedDeviceLink: String = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

    val payloadParts: List<String> = listOf(
        schemeName,
        signatureProtocol,
        rpChallenge,
        relyingPartyNameBase64,
        brokeredRpNameBase64,
        interactions,
        initialCallbackUrl,
        unprotectedDeviceLink
    )

    val authCodePayload: String = payloadParts.joinToString(separator)

    println(authCodePayload)
}
using System;

public class AuthCodePayload
{
    public static void Main()
    {
        string separator = "|";

        string schemeName = "smart-id";
        string signatureProtocol = "ACSP_V2";
        string rpChallenge = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==";
        string relyingPartyNameBase64 = "REVNTw==";
        string brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
        string interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
        string initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        string unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

        string[] payloadParts = {
            schemeName,
            signatureProtocol,
            rpChallenge,
            relyingPartyNameBase64,
            brokeredRpNameBase64,
            interactions,
            initialCallbackUrl,
            unprotectedDeviceLink
        };

        string authCodePayload = string.Join(separator, payloadParts);
        Console.WriteLine(authCodePayload);
    }
}
const separator = '|';

const schemeName = 'smart-id';
const signatureProtocol = 'ACSP_V2';
const rpChallenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==';
const relyingPartyNameBase64 = 'REVNTw==';
const brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
const interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
const initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
const unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

const authCodePayload = [
    schemeName,
    signatureProtocol,
    rpChallenge,
    relyingPartyNameBase64,
    brokeredRpNameBase64,
    interactions,
    initialCallbackUrl,
    unprotectedDeviceLink
].join(separator);

console.log(authCodePayload);
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'ACSP_V2'
rp_challenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = [
    scheme_name,
    signature_protocol,
    rp_challenge,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
].join(separator)

puts auth_code_payload

For signature session device links digest value replaces the rpChallenge, and signatureProtocol value is RAW_DIGEST_SIGNATURE:

authCodePayload := UTF8-ENCODE(STR-CONCAT(
        'smart-id', '|',
        'RAW_DIGEST_SIGNATURE', '|',
        digest, '|',
        BASE64-ENCODE(relyingPartyName), '|',
        BASE64-ENCODE(brokeredRpName), '|',
        interactions, '|',
        initialCallbackUrl, '|',
        unprotectedDeviceLink))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class AuthCodePayload {

  public static void main(String[] args) throws Exception {
    String separator = "|";
    String schemeName = "smart-id";
    String signatureProtocol = "RAW_DIGEST_SIGNATURE";
    String digest = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==";
    String relyingPartyNameBase64 = "REVNTw==";
    String brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
    String interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    String initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    String unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    String[] payloadParts = {
      schemeName,
      signatureProtocol,
      digest,
      relyingPartyNameBase64,
      brokeredRpNameBase64,
      interactions,
      initialCallbackUrl,
      unprotectedDeviceLink
    };

    String authCodePayload = String.join(separator, payloadParts);
    System.out.println(authCodePayload);
  }
}
<?php

$separator = '|';

$schemeName = 'smart-id';
$signatureProtocol = 'RAW_DIGEST_SIGNATURE';
$digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==';
$relyingPartyNameBase64 = 'REVNTw==';
$brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
$interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
$initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
$unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

$authCodePayload = implode($separator, [
    $schemeName,
    $signatureProtocol,
    $digest,
    $relyingPartyNameBase64,
    $brokeredRpNameBase64,
    $interactions,
    $initialCallbackUrl,
    $unprotectedDeviceLink
]);

echo $authCodePayload;

?>
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'RAW_DIGEST_SIGNATURE'
digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = separator.join([
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
])

print(auth_code_payload)
package main

import (
	"fmt"
)

func main() {
	var separator string = "|"

	var schemeName string = "smart-id"
	var signatureProtocol string = "RAW_DIGEST_SIGNATURE"
	var digest string = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=="
	var relyingPartyNameBase64 string = "REVNTw=="
	var brokeredRpNameBase64 string = "RXhhbXBsZSBSUA=="
	var interactions string = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
	var initialCallbackUrl string = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
	var unprotectedDeviceLink string = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

	var payloadParts = []string{
		schemeName,
		signatureProtocol,
		digest,
		relyingPartyNameBase64,
		brokeredRpNameBase64,
		interactions,
		initialCallbackUrl,
		unprotectedDeviceLink,
	}

	var authCodePayload string = strings.Join(payloadParts, separator)

	fmt.Printf("%q\n", authCodePayload)
}
fn main() {
    let separator: &str = "|";
    let scheme_name: &str = "smart-id";
    let signature_protocol: &str = "RAW_DIGEST_SIGNATURE";
    let digest: &str = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==";
    let relying_party_name_base64: &str = "REVNTw==";
    let brokered_rp_name_base64: &str = "RXhhbXBsZSBSUA==";
    let interactions: &str = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    let initial_callback_url: &str = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    let unprotected_device_link: &str = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    let auth_code_payload_parts: [&str; 7] = [
        scheme_name,
        signature_protocol,
        digest,
        relying_party_name_base64,
        brokered_rp_name_base64,
        interactions,
        initial_callback_url,
        unprotected_device_link
    ];

    let auth_code_payload: String = auth_code_payload_parts.join(separator);

    println!("{}", auth_code_payload)
}
fun main() {
    val separator: String = "|"

    val schemeName: String = "smart-id"
    val signatureProtocol: String = "RAW_DIGEST_SIGNATURE"
    val digest: String = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=="
    val relyingPartyNameBase64: String = "REVNTw=="
    val brokeredRpNameBase64: String = "RXhhbXBsZSBSUA=="
    val interactions: String = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
    val initialCallbackUrl: String = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
    val unprotectedDeviceLink: String = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

    val payloadParts: List<String> = listOf(
        schemeName,
        signatureProtocol,
        digest,
        relyingPartyNameBase64,
        brokeredRpNameBase64,
        interactions,
        initialCallbackUrl,
        unprotectedDeviceLink
    )

    val authCodePayload: String = payloadParts.joinToString(separator)

    println(authCodePayload)
}
using System;

public class AuthCodePayload
{
    public static void Main()
    {
        string separator = "|";

        string schemeName = "smart-id";
        string signatureProtocol = "RAW_DIGEST_SIGNATURE";
        string digest = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==";
        string relyingPartyNameBase64 = "REVNTw==";
        string brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
        string interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
        string initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        string unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

        string[] payloadParts = {
            schemeName,
            signatureProtocol,
            digest,
            relyingPartyNameBase64,
            brokeredRpNameBase64,
            interactions,
            initialCallbackUrl,
            unprotectedDeviceLink
        };

        string authCodePayload = string.Join(separator, payloadParts);
        Console.WriteLine(authCodePayload);
    }
}
const separator = '|';

const schemeName = 'smart-id';
const signatureProtocol = 'RAW_DIGEST_SIGNATURE';
const digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==';
const relyingPartyNameBase64 = 'REVNTw==';
const brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
const interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
const initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
const unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

const authCodePayload = [
    schemeName,
    signatureProtocol,
    digest,
    relyingPartyNameBase64,
    brokeredRpNameBase64,
    interactions,
    initialCallbackUrl,
    unprotectedDeviceLink
].join(separator);

console.log(authCodePayload);
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'RAW_DIGEST_SIGNATURE'
digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = [
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
].join(separator)

puts auth_code_payload

For certificate-choice session device links, digest, interactions and signatureProtocol values are omitted:

authCodePayload := UTF8-ENCODE(STR-CONCAT(
        'smart-id', '|',
        '', '|',
        '', '|',
        BASE64-ENCODE(relyingPartyName), '|',
        BASE64-ENCODE(brokeredRpName), '|',
        '', '|',
        initialCallbackUrl, '|',
        unprotectedDeviceLink))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class AuthCodePayload {

  public static void main(String[] args) throws Exception {
    String separator = "|";
    String schemeName = "smart-id";
    String signatureProtocol = "";
    String digest = "";
    String relyingPartyNameBase64 = "REVNTw==";
    String brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
    String interactions = "";
    String initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    String unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    String[] payloadParts = {
      schemeName,
      signatureProtocol,
      digest,
      relyingPartyNameBase64,
      brokeredRpNameBase64,
      interactions,
      initialCallbackUrl,
      unprotectedDeviceLink
    };

    String authCodePayload = String.join(separator, payloadParts);
    System.out.println(authCodePayload);
  }
}
<?php

$separator = '|';

$schemeName = 'smart-id';
$signatureProtocol = '';
$digest = '';
$relyingPartyNameBase64 = 'REVNTw==';
$brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
$interactions = '';
$initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
$unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

$authCodePayload = implode($separator, [
    $schemeName,
    $signatureProtocol,
    $digest,
    $relyingPartyNameBase64,
    $brokeredRpNameBase64,
    $interactions,
    $initialCallbackUrl,
    $unprotectedDeviceLink
]);

echo $authCodePayload;

?>
separator = '|'

scheme_name = 'smart-id'
signature_protocol = ''
digest = ''
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = ''
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = separator.join([
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
])

print(auth_code_payload)
package main

import (
	"fmt"
)

func main() {
	var separator string = "|"

	var schemeName string = "smart-id"
	var signatureProtocol string = ""
	var digest string = ""
	var relyingPartyNameBase64 string = "REVNTw=="
	var brokeredRpNameBase64 string = "RXhhbXBsZSBSUA=="
	var interactions string = ""
	var initialCallbackUrl string = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
	var unprotectedDeviceLink string = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

	var payloadParts = []string{
		schemeName,
		signatureProtocol,
		digest,
		relyingPartyNameBase64,
		brokeredRpNameBase64,
		interactions,
		initialCallbackUrl,
		unprotectedDeviceLink,
	}

	var authCodePayload string = strings.Join(payloadParts, separator)

	fmt.Printf("%q\n", authCodePayload)
}
fn main() {
    let separator: &str = "|";
    let scheme_name: &str = "smart-id";
    let signature_protocol: &str = "";
    let digest: &str = "";
    let relying_party_name_base64: &str = "REVNTw==";
    let brokered_rp_name_base64: &str = "RXhhbXBsZSBSUA==";
    let interactions: &str = "";
    let initial_callback_url: &str = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    let unprotected_device_link: &str = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    let auth_code_payload_parts: [&str; 7] = [
        scheme_name,
        signature_protocol,
        digest,
        relying_party_name_base64,
        brokered_rp_name_base64,
        interactions,
        initial_callback_url,
        unprotected_device_link
    ];

    let auth_code_payload: String = auth_code_payload_parts.join(separator);

    println!("{}", auth_code_payload)
}
fun main() {
    val separator: String = "|"

    val schemeName: String = "smart-id"
    val signatureProtocol: String = ""
    val digest: String = ""
    val relyingPartyNameBase64: String = "REVNTw=="
    val brokeredRpNameBase64: String = "RXhhbXBsZSBSUA=="
    val interactions: String = ""
    val initialCallbackUrl: String = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
    val unprotectedDeviceLink: String = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

    val payloadParts: List<String> = listOf(
        schemeName,
        signatureProtocol,
        digest,
        relyingPartyNameBase64,
        brokeredRpNameBase64,
        interactions,
        initialCallbackUrl,
        unprotectedDeviceLink
    )

    val authCodePayload: String = payloadParts.joinToString(separator)

    println(authCodePayload)
}
using System;

public class AuthCodePayload
{
    public static void Main()
    {
        string separator = "|";

        string schemeName = "smart-id";
        string signatureProtocol = "";
        string digest = "";
        string relyingPartyNameBase64 = "REVNTw==";
        string brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
        string interactions = "";
        string initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        string unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

        string[] payloadParts = {
            schemeName,
            signatureProtocol,
            digest,
            relyingPartyNameBase64,
            brokeredRpNameBase64,
            interactions,
            initialCallbackUrl,
            unprotectedDeviceLink
        };

        string authCodePayload = string.Join(separator, payloadParts);
        Console.WriteLine(authCodePayload);
    }
}
const separator = '|';

const schemeName = 'smart-id';
const signatureProtocol = '';
const digest = '';
const relyingPartyNameBase64 = 'REVNTw==';
const brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
const interactions = '';
const initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
const unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

const authCodePayload = [
    schemeName,
    signatureProtocol,
    digest,
    relyingPartyNameBase64,
    brokeredRpNameBase64,
    interactions,
    initialCallbackUrl,
    unprotectedDeviceLink
].join(separator);

console.log(authCodePayload);
separator = '|'

scheme_name = 'smart-id'
signature_protocol = ''
digest = ''
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = ''
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = [
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
].join(separator)

puts auth_code_payload

After the RP assembles the authCodePayload, authCode can be calculated as follows:

  • Authentication Session

  • Signature Session

  • Certificate-choice Session

authCode := BASE64URL-ENCODE(HMAC-SHA256(sessionSecret, authCodePayload))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AuthCodeCalculator {

  public static void main(String[] args) throws Exception {
    String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

    byte[] sessionSecret = Base64.getDecoder()
      .decode(sessionSecretBase64);

    byte[] authCodePayload = "aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0"
      .getBytes(StandardCharsets.UTF_8);

    Mac sha256Hmac = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(sessionSecret, sha256Hmac.getAlgorithm());
    sha256Hmac.init(secretKey);

    byte[] authCodeBytes = sha256Hmac.doFinal(authCodePayload);

    String authCode = Base64.getUrlEncoder()
      .withoutPadding()
      .encodeToString(authCodeBytes);

    System.out.println(authCode);
  }
}
<?php

$sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
$sessionSecret = base64_decode($sessionSecretBase64);

$authCodePayload = 'aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0';

$authCodeBytes = hash_hmac('sha256', $authCodePayload, $sessionSecret, true);

$authCode = rtrim(strtr(base64_encode($authCodeBytes), '+/', '-_'), '=');

echo $authCode;
?>
import hmac
import hashlib
import base64

session_secret_base64 = b'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = base64.b64decode(session_secret_base64)

auth_code_payload = b'aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0'

auth_code_bytes = hmac.new(session_secret, auth_code_payload, hashlib.sha256).digest()

auth_code = base64.urlsafe_b64encode(auth_code_bytes).rstrip(b'=').decode('utf-8')
print(auth_code)
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
	var authCodePayload []byte = []byte("aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0")

	sessionSecret, err := base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	mac := hmac.New(sha256.New, sessionSecret)
	mac.Write(authCodePayload)
	var authCodeBytes []byte = mac.Sum(nil)

	var authCode string = base64.RawURLEncoding.EncodeToString(authCodeBytes)
	fmt.Printf("%s\n", authCode)
}
use hmac::{Hmac, Mac};
use sha2::Sha256;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret: &[u8] = &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();

    let auth_code_payload: &[u8] = &b"aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0"[..];

    let mut mac = Hmac::<Sha256>::new_from_slice(session_secret).expect("HMAC can take key of any size");
    mac.update(auth_code_payload);

    let auth_code_bytes = mac.finalize().into_bytes();

    const CUSTOM_ENGINE: engine::GeneralPurpose = base64::engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
    let auth_code: String = CUSTOM_ENGINE.encode(auth_code_bytes);
    println!("{}", auth_code)
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
  val sessionSecret: ByteArray = Base64.getDecoder()
    .decode(sessionSecretBase64)

  val authCodePayload: ByteArray = "aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0"
    .toByteArray(StandardCharsets.UTF_8)

  val hmac: Mac = Mac.getInstance("HmacSHA256")
  val secretKey: SecretKey = SecretKeySpec(sessionSecret, hmac.algorithm)
  hmac.init(secretKey)

  val authCodeBytes: ByteArray = hmac.doFinal(authCodePayload)

  val authCode: String = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(authCodeBytes)

  println(authCode)
}
using System;
using System.Text;
using System.Security.Cryptography;

public class AuthCodeCalculator
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecret = Convert.FromBase64String(sessionSecretBase64);
        byte[] authCodePayload = Encoding.UTF8.GetBytes("aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0");

        HMACSHA256 hmac = new HMACSHA256(sessionSecret);
        byte[] authCodeBytes = hmac.ComputeHash(authCodePayload);
        string authCode = Convert.ToBase64String(authCodeBytes)
            .Replace('+', '-')
            .Replace('/', '_')
            .TrimEnd('=');

        Console.WriteLine(authCode);
    }
}
const crypto = require('crypto');

const sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');

const authCodePayload = 'aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0';

const hmac = crypto.createHmac('sha256', sessionSecret);
hmac.update(authCodePayload);

const authCode = hmac.digest('base64url')
    .replace(/=+$/, '');

console.log(authCode);
require 'base64'
require 'openssl'

session_secret_base64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = Base64.decode64(session_secret_base64)

auth_code_payload = 'aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0'

hmac = OpenSSL::HMAC.digest(
  'sha256', session_secret, auth_code_payload
)
auth_code = Base64.urlsafe_encode64(hmac).sub(/=*$/, '')

puts auth_code
Example 1. authCode parameter
aegUh6gCKkXBJhhvtJqSTWB5_2W8TDQt5eZ7db6krv0
authCode := BASE64URL-ENCODE(HMAC-SHA256(sessionSecret, authCodePayload))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AuthCodeCalculator {

  public static void main(String[] args) throws Exception {
    String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

    byte[] sessionSecret = Base64.getDecoder()
      .decode(sessionSecretBase64);

    byte[] authCodePayload = "R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8"
      .getBytes(StandardCharsets.UTF_8);

    Mac sha256Hmac = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(sessionSecret, sha256Hmac.getAlgorithm());
    sha256Hmac.init(secretKey);

    byte[] authCodeBytes = sha256Hmac.doFinal(authCodePayload);

    String authCode = Base64.getUrlEncoder()
      .withoutPadding()
      .encodeToString(authCodeBytes);

    System.out.println(authCode);
  }
}
<?php

$sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
$sessionSecret = base64_decode($sessionSecretBase64);

$authCodePayload = 'R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8';

$authCodeBytes = hash_hmac('sha256', $authCodePayload, $sessionSecret, true);

$authCode = rtrim(strtr(base64_encode($authCodeBytes), '+/', '-_'), '=');

echo $authCode;
?>
import hmac
import hashlib
import base64

session_secret_base64 = b'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = base64.b64decode(session_secret_base64)

auth_code_payload = b'R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8'

auth_code_bytes = hmac.new(session_secret, auth_code_payload, hashlib.sha256).digest()

auth_code = base64.urlsafe_b64encode(auth_code_bytes).rstrip(b'=').decode('utf-8')
print(auth_code)
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
	var authCodePayload []byte = []byte("R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8")

	sessionSecret, err := base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	mac := hmac.New(sha256.New, sessionSecret)
	mac.Write(authCodePayload)
	var authCodeBytes []byte = mac.Sum(nil)

	var authCode string = base64.RawURLEncoding.EncodeToString(authCodeBytes)
	fmt.Printf("%s\n", authCode)
}
use hmac::{Hmac, Mac};
use sha2::Sha256;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret: &[u8] = &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();

    let auth_code_payload: &[u8] = &b"R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8"[..];

    let mut mac = Hmac::<Sha256>::new_from_slice(session_secret).expect("HMAC can take key of any size");
    mac.update(auth_code_payload);

    let auth_code_bytes = mac.finalize().into_bytes();

    const CUSTOM_ENGINE: engine::GeneralPurpose = base64::engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
    let auth_code: String = CUSTOM_ENGINE.encode(auth_code_bytes);
    println!("{}", auth_code)
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
  val sessionSecret: ByteArray = Base64.getDecoder()
    .decode(sessionSecretBase64)

  val authCodePayload: ByteArray = "R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8"
    .toByteArray(StandardCharsets.UTF_8)

  val hmac: Mac = Mac.getInstance("HmacSHA256")
  val secretKey: SecretKey = SecretKeySpec(sessionSecret, hmac.algorithm)
  hmac.init(secretKey)

  val authCodeBytes: ByteArray = hmac.doFinal(authCodePayload)

  val authCode: String = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(authCodeBytes)

  println(authCode)
}
using System;
using System.Text;
using System.Security.Cryptography;

public class AuthCodeCalculator
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecret = Convert.FromBase64String(sessionSecretBase64);
        byte[] authCodePayload = Encoding.UTF8.GetBytes("R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8");

        HMACSHA256 hmac = new HMACSHA256(sessionSecret);
        byte[] authCodeBytes = hmac.ComputeHash(authCodePayload);
        string authCode = Convert.ToBase64String(authCodeBytes)
            .Replace('+', '-')
            .Replace('/', '_')
            .TrimEnd('=');

        Console.WriteLine(authCode);
    }
}
const crypto = require('crypto');

const sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');

const authCodePayload = 'R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8';

const hmac = crypto.createHmac('sha256', sessionSecret);
hmac.update(authCodePayload);

const authCode = hmac.digest('base64url')
    .replace(/=+$/, '');

console.log(authCode);
require 'base64'
require 'openssl'

session_secret_base64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = Base64.decode64(session_secret_base64)

auth_code_payload = 'R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8'

hmac = OpenSSL::HMAC.digest(
  'sha256', session_secret, auth_code_payload
)
auth_code = Base64.urlsafe_encode64(hmac).sub(/=*$/, '')

puts auth_code
Example 2. authCode parameter
R0iNcUp8nK1nqrcVFWerXUfWMSjwDOMC6MAHKrckaH8
authCode := BASE64URL-ENCODE(HMAC-SHA256(sessionSecret, authCodePayload))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AuthCodeCalculator {

  public static void main(String[] args) throws Exception {
    String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

    byte[] sessionSecret = Base64.getDecoder()
      .decode(sessionSecretBase64);

    byte[] authCodePayload = "PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg"
      .getBytes(StandardCharsets.UTF_8);

    Mac sha256Hmac = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(sessionSecret, sha256Hmac.getAlgorithm());
    sha256Hmac.init(secretKey);

    byte[] authCodeBytes = sha256Hmac.doFinal(authCodePayload);

    String authCode = Base64.getUrlEncoder()
      .withoutPadding()
      .encodeToString(authCodeBytes);

    System.out.println(authCode);
  }
}
<?php

$sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
$sessionSecret = base64_decode($sessionSecretBase64);

$authCodePayload = 'PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg';

$authCodeBytes = hash_hmac('sha256', $authCodePayload, $sessionSecret, true);

$authCode = rtrim(strtr(base64_encode($authCodeBytes), '+/', '-_'), '=');

echo $authCode;
?>
import hmac
import hashlib
import base64

session_secret_base64 = b'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = base64.b64decode(session_secret_base64)

auth_code_payload = b'PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg'

auth_code_bytes = hmac.new(session_secret, auth_code_payload, hashlib.sha256).digest()

auth_code = base64.urlsafe_b64encode(auth_code_bytes).rstrip(b'=').decode('utf-8')
print(auth_code)
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
	var authCodePayload []byte = []byte("PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg")

	sessionSecret, err := base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	mac := hmac.New(sha256.New, sessionSecret)
	mac.Write(authCodePayload)
	var authCodeBytes []byte = mac.Sum(nil)

	var authCode string = base64.RawURLEncoding.EncodeToString(authCodeBytes)
	fmt.Printf("%s\n", authCode)
}
use hmac::{Hmac, Mac};
use sha2::Sha256;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret: &[u8] = &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();

    let auth_code_payload: &[u8] = &b"PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg"[..];

    let mut mac = Hmac::<Sha256>::new_from_slice(session_secret).expect("HMAC can take key of any size");
    mac.update(auth_code_payload);

    let auth_code_bytes = mac.finalize().into_bytes();

    const CUSTOM_ENGINE: engine::GeneralPurpose = base64::engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
    let auth_code: String = CUSTOM_ENGINE.encode(auth_code_bytes);
    println!("{}", auth_code)
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
  val sessionSecret: ByteArray = Base64.getDecoder()
    .decode(sessionSecretBase64)

  val authCodePayload: ByteArray = "PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg"
    .toByteArray(StandardCharsets.UTF_8)

  val hmac: Mac = Mac.getInstance("HmacSHA256")
  val secretKey: SecretKey = SecretKeySpec(sessionSecret, hmac.algorithm)
  hmac.init(secretKey)

  val authCodeBytes: ByteArray = hmac.doFinal(authCodePayload)

  val authCode: String = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(authCodeBytes)

  println(authCode)
}
using System;
using System.Text;
using System.Security.Cryptography;

public class AuthCodeCalculator
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecret = Convert.FromBase64String(sessionSecretBase64);
        byte[] authCodePayload = Encoding.UTF8.GetBytes("PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg");

        HMACSHA256 hmac = new HMACSHA256(sessionSecret);
        byte[] authCodeBytes = hmac.ComputeHash(authCodePayload);
        string authCode = Convert.ToBase64String(authCodeBytes)
            .Replace('+', '-')
            .Replace('/', '_')
            .TrimEnd('=');

        Console.WriteLine(authCode);
    }
}
const crypto = require('crypto');

const sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');

const authCodePayload = 'PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg';

const hmac = crypto.createHmac('sha256', sessionSecret);
hmac.update(authCodePayload);

const authCode = hmac.digest('base64url')
    .replace(/=+$/, '');

console.log(authCode);
require 'base64'
require 'openssl'

session_secret_base64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = Base64.decode64(session_secret_base64)

auth_code_payload = 'PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg'

hmac = OpenSSL::HMAC.digest(
  'sha256', session_secret, auth_code_payload
)
auth_code = Base64.urlsafe_encode64(hmac).sub(/=*$/, '')

puts auth_code
Example 3. authCode parameter
PI1qYa9_l6zR-v6Pkre6ycSm7S3BGiOQSe5OQlw4UJg
  • Authentication Session

  • Signature Session

  • Certificate-choice Session

For authentication session device links signatureProtocol value is ACSP_V2:

authCodePayload := UTF8-ENCODE(STR-CONCAT(
        'smart-id', '|',
        'ACSP_V2', '|',
        rpChallenge, '|',
        BASE64-ENCODE(relyingPartyName), '|',
        BASE64-ENCODE(brokeredRpName), '|',
        interactions, '|',
        initialCallbackUrl, '|',
        unprotectedDeviceLink))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class AuthCodePayload {

  public static void main(String[] args) throws Exception {
    String separator = "|";
    String schemeName = "smart-id";
    String signatureProtocol = "ACSP_V2";
    String rpChallenge = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==";
    String relyingPartyNameBase64 = "REVNTw==";
    String brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
    String interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    String initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    String unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    String[] payloadParts = {
      schemeName,
      signatureProtocol,
      rpChallenge,
      relyingPartyNameBase64,
      brokeredRpNameBase64,
      interactions,
      initialCallbackUrl,
      unprotectedDeviceLink
    };

    String authCodePayload = String.join(separator, payloadParts);
    System.out.println(authCodePayload);
  }
}
<?php

$separator = '|';

$schemeName = 'smart-id';
$signatureProtocol = 'ACSP_V2';
$rpChallenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==';
$relyingPartyNameBase64 = 'REVNTw==';
$brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
$interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
$initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
$unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

$authCodePayload = implode($separator, [
    $schemeName,
    $signatureProtocol,
    $rpChallenge,
    $relyingPartyNameBase64,
    $brokeredRpNameBase64,
    $interactions,
    $initialCallbackUrl,
    $unprotectedDeviceLink
]);

echo $authCodePayload;

?>
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'ACSP_V2'
rp_challenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = separator.join([
    scheme_name,
    signature_protocol,
    rp_challenge,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
])

print(auth_code_payload)
package main

import (
	"fmt"
)

func main() {
	var separator string = "|"

	var schemeName string = "smart-id"
	var signatureProtocol string = "ACSP_V2"
	var rpChallenge string = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=="
	var relyingPartyNameBase64 string = "REVNTw=="
	var brokeredRpNameBase64 string = "RXhhbXBsZSBSUA=="
	var interactions string = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
	var initialCallbackUrl string = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
	var unprotectedDeviceLink string = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

	var payloadParts = []string{
		schemeName,
		signatureProtocol,
		rpChallenge,
		relyingPartyNameBase64,
		brokeredRpNameBase64,
		interactions,
		initialCallbackUrl,
		unprotectedDeviceLink,
	}

	var authCodePayload string = strings.Join(payloadParts, separator)

	fmt.Printf("%q\n", authCodePayload)
}
fn main() {
    let separator: &str = "|";
    let scheme_name: &str = "smart-id";
    let signature_protocol: &str = "ACSP_V2";
    let rp_challenge: &str = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==";
    let relying_party_name_base64: &str = "REVNTw==";
    let brokered_rp_name_base64: &str = "RXhhbXBsZSBSUA==";
    let interactions: &str = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    let initial_callback_url: &str = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    let unprotected_device_link: &str = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    let auth_code_payload_parts: [&str; 7] = [
        scheme_name,
        signature_protocol,
        rp_challenge,
        relying_party_name_base64,
        brokered_rp_name_base64,
        interactions,
        initial_callback_url,
        unprotected_device_link
    ];

    let auth_code_payload: String = auth_code_payload_parts.join(separator);

    println!("{}", auth_code_payload)
}
fun main() {
    val separator: String = "|"

    val schemeName: String = "smart-id"
    val signatureProtocol: String = "ACSP_V2"
    val rpChallenge: String = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=="
    val relyingPartyNameBase64: String = "REVNTw=="
    val brokeredRpNameBase64: String = "RXhhbXBsZSBSUA=="
    val interactions: String = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
    val initialCallbackUrl: String = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
    val unprotectedDeviceLink: String = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

    val payloadParts: List<String> = listOf(
        schemeName,
        signatureProtocol,
        rpChallenge,
        relyingPartyNameBase64,
        brokeredRpNameBase64,
        interactions,
        initialCallbackUrl,
        unprotectedDeviceLink
    )

    val authCodePayload: String = payloadParts.joinToString(separator)

    println(authCodePayload)
}
using System;

public class AuthCodePayload
{
    public static void Main()
    {
        string separator = "|";

        string schemeName = "smart-id";
        string signatureProtocol = "ACSP_V2";
        string rpChallenge = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==";
        string relyingPartyNameBase64 = "REVNTw==";
        string brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
        string interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
        string initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        string unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

        string[] payloadParts = {
            schemeName,
            signatureProtocol,
            rpChallenge,
            relyingPartyNameBase64,
            brokeredRpNameBase64,
            interactions,
            initialCallbackUrl,
            unprotectedDeviceLink
        };

        string authCodePayload = string.Join(separator, payloadParts);
        Console.WriteLine(authCodePayload);
    }
}
const separator = '|';

const schemeName = 'smart-id';
const signatureProtocol = 'ACSP_V2';
const rpChallenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==';
const relyingPartyNameBase64 = 'REVNTw==';
const brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
const interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
const initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
const unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

const authCodePayload = [
    schemeName,
    signatureProtocol,
    rpChallenge,
    relyingPartyNameBase64,
    brokeredRpNameBase64,
    interactions,
    initialCallbackUrl,
    unprotectedDeviceLink
].join(separator);

console.log(authCodePayload);
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'ACSP_V2'
rp_challenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = [
    scheme_name,
    signature_protocol,
    rp_challenge,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
].join(separator)

puts auth_code_payload

For signature session device links digest value replaces the rpChallenge, and signatureProtocol value is RAW_DIGEST_SIGNATURE:

authCodePayload := UTF8-ENCODE(STR-CONCAT(
        'smart-id', '|',
        'RAW_DIGEST_SIGNATURE', '|',
        digest, '|',
        BASE64-ENCODE(relyingPartyName), '|',
        BASE64-ENCODE(brokeredRpName), '|',
        interactions, '|',
        initialCallbackUrl, '|',
        unprotectedDeviceLink))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class AuthCodePayload {

  public static void main(String[] args) throws Exception {
    String separator = "|";
    String schemeName = "smart-id";
    String signatureProtocol = "RAW_DIGEST_SIGNATURE";
    String digest = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==";
    String relyingPartyNameBase64 = "REVNTw==";
    String brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
    String interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    String initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    String unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    String[] payloadParts = {
      schemeName,
      signatureProtocol,
      digest,
      relyingPartyNameBase64,
      brokeredRpNameBase64,
      interactions,
      initialCallbackUrl,
      unprotectedDeviceLink
    };

    String authCodePayload = String.join(separator, payloadParts);
    System.out.println(authCodePayload);
  }
}
<?php

$separator = '|';

$schemeName = 'smart-id';
$signatureProtocol = 'RAW_DIGEST_SIGNATURE';
$digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==';
$relyingPartyNameBase64 = 'REVNTw==';
$brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
$interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
$initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
$unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

$authCodePayload = implode($separator, [
    $schemeName,
    $signatureProtocol,
    $digest,
    $relyingPartyNameBase64,
    $brokeredRpNameBase64,
    $interactions,
    $initialCallbackUrl,
    $unprotectedDeviceLink
]);

echo $authCodePayload;

?>
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'RAW_DIGEST_SIGNATURE'
digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = separator.join([
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
])

print(auth_code_payload)
package main

import (
	"fmt"
)

func main() {
	var separator string = "|"

	var schemeName string = "smart-id"
	var signatureProtocol string = "RAW_DIGEST_SIGNATURE"
	var digest string = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=="
	var relyingPartyNameBase64 string = "REVNTw=="
	var brokeredRpNameBase64 string = "RXhhbXBsZSBSUA=="
	var interactions string = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
	var initialCallbackUrl string = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
	var unprotectedDeviceLink string = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

	var payloadParts = []string{
		schemeName,
		signatureProtocol,
		digest,
		relyingPartyNameBase64,
		brokeredRpNameBase64,
		interactions,
		initialCallbackUrl,
		unprotectedDeviceLink,
	}

	var authCodePayload string = strings.Join(payloadParts, separator)

	fmt.Printf("%q\n", authCodePayload)
}
fn main() {
    let separator: &str = "|";
    let scheme_name: &str = "smart-id";
    let signature_protocol: &str = "RAW_DIGEST_SIGNATURE";
    let digest: &str = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==";
    let relying_party_name_base64: &str = "REVNTw==";
    let brokered_rp_name_base64: &str = "RXhhbXBsZSBSUA==";
    let interactions: &str = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    let initial_callback_url: &str = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    let unprotected_device_link: &str = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    let auth_code_payload_parts: [&str; 7] = [
        scheme_name,
        signature_protocol,
        digest,
        relying_party_name_base64,
        brokered_rp_name_base64,
        interactions,
        initial_callback_url,
        unprotected_device_link
    ];

    let auth_code_payload: String = auth_code_payload_parts.join(separator);

    println!("{}", auth_code_payload)
}
fun main() {
    val separator: String = "|"

    val schemeName: String = "smart-id"
    val signatureProtocol: String = "RAW_DIGEST_SIGNATURE"
    val digest: String = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=="
    val relyingPartyNameBase64: String = "REVNTw=="
    val brokeredRpNameBase64: String = "RXhhbXBsZSBSUA=="
    val interactions: String = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
    val initialCallbackUrl: String = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
    val unprotectedDeviceLink: String = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

    val payloadParts: List<String> = listOf(
        schemeName,
        signatureProtocol,
        digest,
        relyingPartyNameBase64,
        brokeredRpNameBase64,
        interactions,
        initialCallbackUrl,
        unprotectedDeviceLink
    )

    val authCodePayload: String = payloadParts.joinToString(separator)

    println(authCodePayload)
}
using System;

public class AuthCodePayload
{
    public static void Main()
    {
        string separator = "|";

        string schemeName = "smart-id";
        string signatureProtocol = "RAW_DIGEST_SIGNATURE";
        string digest = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==";
        string relyingPartyNameBase64 = "REVNTw==";
        string brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
        string interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
        string initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        string unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

        string[] payloadParts = {
            schemeName,
            signatureProtocol,
            digest,
            relyingPartyNameBase64,
            brokeredRpNameBase64,
            interactions,
            initialCallbackUrl,
            unprotectedDeviceLink
        };

        string authCodePayload = string.Join(separator, payloadParts);
        Console.WriteLine(authCodePayload);
    }
}
const separator = '|';

const schemeName = 'smart-id';
const signatureProtocol = 'RAW_DIGEST_SIGNATURE';
const digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==';
const relyingPartyNameBase64 = 'REVNTw==';
const brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
const interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
const initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
const unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

const authCodePayload = [
    schemeName,
    signatureProtocol,
    digest,
    relyingPartyNameBase64,
    brokeredRpNameBase64,
    interactions,
    initialCallbackUrl,
    unprotectedDeviceLink
].join(separator);

console.log(authCodePayload);
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'RAW_DIGEST_SIGNATURE'
digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = [
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
].join(separator)

puts auth_code_payload

For certificate-choice session device links, digest, interactions and signatureProtocol values are omitted:

authCodePayload := UTF8-ENCODE(STR-CONCAT(
        'smart-id', '|',
        '', '|',
        '', '|',
        BASE64-ENCODE(relyingPartyName), '|',
        BASE64-ENCODE(brokeredRpName), '|',
        '', '|',
        initialCallbackUrl, '|',
        unprotectedDeviceLink))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class AuthCodePayload {

  public static void main(String[] args) throws Exception {
    String separator = "|";
    String schemeName = "smart-id";
    String signatureProtocol = "";
    String digest = "";
    String relyingPartyNameBase64 = "REVNTw==";
    String brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
    String interactions = "";
    String initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    String unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    String[] payloadParts = {
      schemeName,
      signatureProtocol,
      digest,
      relyingPartyNameBase64,
      brokeredRpNameBase64,
      interactions,
      initialCallbackUrl,
      unprotectedDeviceLink
    };

    String authCodePayload = String.join(separator, payloadParts);
    System.out.println(authCodePayload);
  }
}
<?php

$separator = '|';

$schemeName = 'smart-id';
$signatureProtocol = '';
$digest = '';
$relyingPartyNameBase64 = 'REVNTw==';
$brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
$interactions = '';
$initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
$unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

$authCodePayload = implode($separator, [
    $schemeName,
    $signatureProtocol,
    $digest,
    $relyingPartyNameBase64,
    $brokeredRpNameBase64,
    $interactions,
    $initialCallbackUrl,
    $unprotectedDeviceLink
]);

echo $authCodePayload;

?>
separator = '|'

scheme_name = 'smart-id'
signature_protocol = ''
digest = ''
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = ''
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = separator.join([
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
])

print(auth_code_payload)
package main

import (
	"fmt"
)

func main() {
	var separator string = "|"

	var schemeName string = "smart-id"
	var signatureProtocol string = ""
	var digest string = ""
	var relyingPartyNameBase64 string = "REVNTw=="
	var brokeredRpNameBase64 string = "RXhhbXBsZSBSUA=="
	var interactions string = ""
	var initialCallbackUrl string = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
	var unprotectedDeviceLink string = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

	var payloadParts = []string{
		schemeName,
		signatureProtocol,
		digest,
		relyingPartyNameBase64,
		brokeredRpNameBase64,
		interactions,
		initialCallbackUrl,
		unprotectedDeviceLink,
	}

	var authCodePayload string = strings.Join(payloadParts, separator)

	fmt.Printf("%q\n", authCodePayload)
}
fn main() {
    let separator: &str = "|";
    let scheme_name: &str = "smart-id";
    let signature_protocol: &str = "";
    let digest: &str = "";
    let relying_party_name_base64: &str = "REVNTw==";
    let brokered_rp_name_base64: &str = "RXhhbXBsZSBSUA==";
    let interactions: &str = "";
    let initial_callback_url: &str = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    let unprotected_device_link: &str = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    let auth_code_payload_parts: [&str; 7] = [
        scheme_name,
        signature_protocol,
        digest,
        relying_party_name_base64,
        brokered_rp_name_base64,
        interactions,
        initial_callback_url,
        unprotected_device_link
    ];

    let auth_code_payload: String = auth_code_payload_parts.join(separator);

    println!("{}", auth_code_payload)
}
fun main() {
    val separator: String = "|"

    val schemeName: String = "smart-id"
    val signatureProtocol: String = ""
    val digest: String = ""
    val relyingPartyNameBase64: String = "REVNTw=="
    val brokeredRpNameBase64: String = "RXhhbXBsZSBSUA=="
    val interactions: String = ""
    val initialCallbackUrl: String = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
    val unprotectedDeviceLink: String = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

    val payloadParts: List<String> = listOf(
        schemeName,
        signatureProtocol,
        digest,
        relyingPartyNameBase64,
        brokeredRpNameBase64,
        interactions,
        initialCallbackUrl,
        unprotectedDeviceLink
    )

    val authCodePayload: String = payloadParts.joinToString(separator)

    println(authCodePayload)
}
using System;

public class AuthCodePayload
{
    public static void Main()
    {
        string separator = "|";

        string schemeName = "smart-id";
        string signatureProtocol = "";
        string digest = "";
        string relyingPartyNameBase64 = "REVNTw==";
        string brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
        string interactions = "";
        string initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        string unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

        string[] payloadParts = {
            schemeName,
            signatureProtocol,
            digest,
            relyingPartyNameBase64,
            brokeredRpNameBase64,
            interactions,
            initialCallbackUrl,
            unprotectedDeviceLink
        };

        string authCodePayload = string.Join(separator, payloadParts);
        Console.WriteLine(authCodePayload);
    }
}
const separator = '|';

const schemeName = 'smart-id';
const signatureProtocol = '';
const digest = '';
const relyingPartyNameBase64 = 'REVNTw==';
const brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
const interactions = '';
const initialCallbackUrl = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ';
const unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

const authCodePayload = [
    schemeName,
    signatureProtocol,
    digest,
    relyingPartyNameBase64,
    brokeredRpNameBase64,
    interactions,
    initialCallbackUrl,
    unprotectedDeviceLink
].join(separator);

console.log(authCodePayload);
separator = '|'

scheme_name = 'smart-id'
signature_protocol = ''
digest = ''
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = ''
initial_callback_url = 'https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ'
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = [
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
].join(separator)

puts auth_code_payload

After the RP assembles the authCodePayload, authCode can be calculated as follows:

  • Authentication Session

  • Signature Session

  • Certificate-choice Session

authCode := BASE64URL-ENCODE(HMAC-SHA256(sessionSecret, authCodePayload))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AuthCodeCalculator {

  public static void main(String[] args) throws Exception {
    String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

    byte[] sessionSecret = Base64.getDecoder()
      .decode(sessionSecretBase64);

    byte[] authCodePayload = "00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo"
      .getBytes(StandardCharsets.UTF_8);

    Mac sha256Hmac = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(sessionSecret, sha256Hmac.getAlgorithm());
    sha256Hmac.init(secretKey);

    byte[] authCodeBytes = sha256Hmac.doFinal(authCodePayload);

    String authCode = Base64.getUrlEncoder()
      .withoutPadding()
      .encodeToString(authCodeBytes);

    System.out.println(authCode);
  }
}
<?php

$sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
$sessionSecret = base64_decode($sessionSecretBase64);

$authCodePayload = '00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo';

$authCodeBytes = hash_hmac('sha256', $authCodePayload, $sessionSecret, true);

$authCode = rtrim(strtr(base64_encode($authCodeBytes), '+/', '-_'), '=');

echo $authCode;
?>
import hmac
import hashlib
import base64

session_secret_base64 = b'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = base64.b64decode(session_secret_base64)

auth_code_payload = b'00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo'

auth_code_bytes = hmac.new(session_secret, auth_code_payload, hashlib.sha256).digest()

auth_code = base64.urlsafe_b64encode(auth_code_bytes).rstrip(b'=').decode('utf-8')
print(auth_code)
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
	var authCodePayload []byte = []byte("00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo")

	sessionSecret, err := base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	mac := hmac.New(sha256.New, sessionSecret)
	mac.Write(authCodePayload)
	var authCodeBytes []byte = mac.Sum(nil)

	var authCode string = base64.RawURLEncoding.EncodeToString(authCodeBytes)
	fmt.Printf("%s\n", authCode)
}
use hmac::{Hmac, Mac};
use sha2::Sha256;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret: &[u8] = &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();

    let auth_code_payload: &[u8] = &b"00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo"[..];

    let mut mac = Hmac::<Sha256>::new_from_slice(session_secret).expect("HMAC can take key of any size");
    mac.update(auth_code_payload);

    let auth_code_bytes = mac.finalize().into_bytes();

    const CUSTOM_ENGINE: engine::GeneralPurpose = base64::engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
    let auth_code: String = CUSTOM_ENGINE.encode(auth_code_bytes);
    println!("{}", auth_code)
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
  val sessionSecret: ByteArray = Base64.getDecoder()
    .decode(sessionSecretBase64)

  val authCodePayload: ByteArray = "00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo"
    .toByteArray(StandardCharsets.UTF_8)

  val hmac: Mac = Mac.getInstance("HmacSHA256")
  val secretKey: SecretKey = SecretKeySpec(sessionSecret, hmac.algorithm)
  hmac.init(secretKey)

  val authCodeBytes: ByteArray = hmac.doFinal(authCodePayload)

  val authCode: String = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(authCodeBytes)

  println(authCode)
}
using System;
using System.Text;
using System.Security.Cryptography;

public class AuthCodeCalculator
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecret = Convert.FromBase64String(sessionSecretBase64);
        byte[] authCodePayload = Encoding.UTF8.GetBytes("00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo");

        HMACSHA256 hmac = new HMACSHA256(sessionSecret);
        byte[] authCodeBytes = hmac.ComputeHash(authCodePayload);
        string authCode = Convert.ToBase64String(authCodeBytes)
            .Replace('+', '-')
            .Replace('/', '_')
            .TrimEnd('=');

        Console.WriteLine(authCode);
    }
}
const crypto = require('crypto');

const sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');

const authCodePayload = '00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo';

const hmac = crypto.createHmac('sha256', sessionSecret);
hmac.update(authCodePayload);

const authCode = hmac.digest('base64url')
    .replace(/=+$/, '');

console.log(authCode);
require 'base64'
require 'openssl'

session_secret_base64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = Base64.decode64(session_secret_base64)

auth_code_payload = '00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo'

hmac = OpenSSL::HMAC.digest(
  'sha256', session_secret, auth_code_payload
)
auth_code = Base64.urlsafe_encode64(hmac).sub(/=*$/, '')

puts auth_code
Example 4. authCode parameter
00NRcgi4Jk7WdIwgMPlyM8wRy9KMu4C_oQvd-N6PKoo
authCode := BASE64URL-ENCODE(HMAC-SHA256(sessionSecret, authCodePayload))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AuthCodeCalculator {

  public static void main(String[] args) throws Exception {
    String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

    byte[] sessionSecret = Base64.getDecoder()
      .decode(sessionSecretBase64);

    byte[] authCodePayload = "8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM"
      .getBytes(StandardCharsets.UTF_8);

    Mac sha256Hmac = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(sessionSecret, sha256Hmac.getAlgorithm());
    sha256Hmac.init(secretKey);

    byte[] authCodeBytes = sha256Hmac.doFinal(authCodePayload);

    String authCode = Base64.getUrlEncoder()
      .withoutPadding()
      .encodeToString(authCodeBytes);

    System.out.println(authCode);
  }
}
<?php

$sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
$sessionSecret = base64_decode($sessionSecretBase64);

$authCodePayload = '8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM';

$authCodeBytes = hash_hmac('sha256', $authCodePayload, $sessionSecret, true);

$authCode = rtrim(strtr(base64_encode($authCodeBytes), '+/', '-_'), '=');

echo $authCode;
?>
import hmac
import hashlib
import base64

session_secret_base64 = b'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = base64.b64decode(session_secret_base64)

auth_code_payload = b'8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM'

auth_code_bytes = hmac.new(session_secret, auth_code_payload, hashlib.sha256).digest()

auth_code = base64.urlsafe_b64encode(auth_code_bytes).rstrip(b'=').decode('utf-8')
print(auth_code)
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
	var authCodePayload []byte = []byte("8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM")

	sessionSecret, err := base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	mac := hmac.New(sha256.New, sessionSecret)
	mac.Write(authCodePayload)
	var authCodeBytes []byte = mac.Sum(nil)

	var authCode string = base64.RawURLEncoding.EncodeToString(authCodeBytes)
	fmt.Printf("%s\n", authCode)
}
use hmac::{Hmac, Mac};
use sha2::Sha256;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret: &[u8] = &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();

    let auth_code_payload: &[u8] = &b"8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM"[..];

    let mut mac = Hmac::<Sha256>::new_from_slice(session_secret).expect("HMAC can take key of any size");
    mac.update(auth_code_payload);

    let auth_code_bytes = mac.finalize().into_bytes();

    const CUSTOM_ENGINE: engine::GeneralPurpose = base64::engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
    let auth_code: String = CUSTOM_ENGINE.encode(auth_code_bytes);
    println!("{}", auth_code)
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
  val sessionSecret: ByteArray = Base64.getDecoder()
    .decode(sessionSecretBase64)

  val authCodePayload: ByteArray = "8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM"
    .toByteArray(StandardCharsets.UTF_8)

  val hmac: Mac = Mac.getInstance("HmacSHA256")
  val secretKey: SecretKey = SecretKeySpec(sessionSecret, hmac.algorithm)
  hmac.init(secretKey)

  val authCodeBytes: ByteArray = hmac.doFinal(authCodePayload)

  val authCode: String = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(authCodeBytes)

  println(authCode)
}
using System;
using System.Text;
using System.Security.Cryptography;

public class AuthCodeCalculator
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecret = Convert.FromBase64String(sessionSecretBase64);
        byte[] authCodePayload = Encoding.UTF8.GetBytes("8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM");

        HMACSHA256 hmac = new HMACSHA256(sessionSecret);
        byte[] authCodeBytes = hmac.ComputeHash(authCodePayload);
        string authCode = Convert.ToBase64String(authCodeBytes)
            .Replace('+', '-')
            .Replace('/', '_')
            .TrimEnd('=');

        Console.WriteLine(authCode);
    }
}
const crypto = require('crypto');

const sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');

const authCodePayload = '8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM';

const hmac = crypto.createHmac('sha256', sessionSecret);
hmac.update(authCodePayload);

const authCode = hmac.digest('base64url')
    .replace(/=+$/, '');

console.log(authCode);
require 'base64'
require 'openssl'

session_secret_base64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = Base64.decode64(session_secret_base64)

auth_code_payload = '8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM'

hmac = OpenSSL::HMAC.digest(
  'sha256', session_secret, auth_code_payload
)
auth_code = Base64.urlsafe_encode64(hmac).sub(/=*$/, '')

puts auth_code
Example 5. authCode parameter
8QZ16rkBW_ffkq6osT7UH1DbUlF9gEOZevgj-A0VNbM
authCode := BASE64URL-ENCODE(HMAC-SHA256(sessionSecret, authCodePayload))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AuthCodeCalculator {

  public static void main(String[] args) throws Exception {
    String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

    byte[] sessionSecret = Base64.getDecoder()
      .decode(sessionSecretBase64);

    byte[] authCodePayload = "AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU"
      .getBytes(StandardCharsets.UTF_8);

    Mac sha256Hmac = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(sessionSecret, sha256Hmac.getAlgorithm());
    sha256Hmac.init(secretKey);

    byte[] authCodeBytes = sha256Hmac.doFinal(authCodePayload);

    String authCode = Base64.getUrlEncoder()
      .withoutPadding()
      .encodeToString(authCodeBytes);

    System.out.println(authCode);
  }
}
<?php

$sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
$sessionSecret = base64_decode($sessionSecretBase64);

$authCodePayload = 'AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU';

$authCodeBytes = hash_hmac('sha256', $authCodePayload, $sessionSecret, true);

$authCode = rtrim(strtr(base64_encode($authCodeBytes), '+/', '-_'), '=');

echo $authCode;
?>
import hmac
import hashlib
import base64

session_secret_base64 = b'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = base64.b64decode(session_secret_base64)

auth_code_payload = b'AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU'

auth_code_bytes = hmac.new(session_secret, auth_code_payload, hashlib.sha256).digest()

auth_code = base64.urlsafe_b64encode(auth_code_bytes).rstrip(b'=').decode('utf-8')
print(auth_code)
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
	var authCodePayload []byte = []byte("AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU")

	sessionSecret, err := base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	mac := hmac.New(sha256.New, sessionSecret)
	mac.Write(authCodePayload)
	var authCodeBytes []byte = mac.Sum(nil)

	var authCode string = base64.RawURLEncoding.EncodeToString(authCodeBytes)
	fmt.Printf("%s\n", authCode)
}
use hmac::{Hmac, Mac};
use sha2::Sha256;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret: &[u8] = &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();

    let auth_code_payload: &[u8] = &b"AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU"[..];

    let mut mac = Hmac::<Sha256>::new_from_slice(session_secret).expect("HMAC can take key of any size");
    mac.update(auth_code_payload);

    let auth_code_bytes = mac.finalize().into_bytes();

    const CUSTOM_ENGINE: engine::GeneralPurpose = base64::engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
    let auth_code: String = CUSTOM_ENGINE.encode(auth_code_bytes);
    println!("{}", auth_code)
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
  val sessionSecret: ByteArray = Base64.getDecoder()
    .decode(sessionSecretBase64)

  val authCodePayload: ByteArray = "AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU"
    .toByteArray(StandardCharsets.UTF_8)

  val hmac: Mac = Mac.getInstance("HmacSHA256")
  val secretKey: SecretKey = SecretKeySpec(sessionSecret, hmac.algorithm)
  hmac.init(secretKey)

  val authCodeBytes: ByteArray = hmac.doFinal(authCodePayload)

  val authCode: String = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(authCodeBytes)

  println(authCode)
}
using System;
using System.Text;
using System.Security.Cryptography;

public class AuthCodeCalculator
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecret = Convert.FromBase64String(sessionSecretBase64);
        byte[] authCodePayload = Encoding.UTF8.GetBytes("AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU");

        HMACSHA256 hmac = new HMACSHA256(sessionSecret);
        byte[] authCodeBytes = hmac.ComputeHash(authCodePayload);
        string authCode = Convert.ToBase64String(authCodeBytes)
            .Replace('+', '-')
            .Replace('/', '_')
            .TrimEnd('=');

        Console.WriteLine(authCode);
    }
}
const crypto = require('crypto');

const sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');

const authCodePayload = 'AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU';

const hmac = crypto.createHmac('sha256', sessionSecret);
hmac.update(authCodePayload);

const authCode = hmac.digest('base64url')
    .replace(/=+$/, '');

console.log(authCode);
require 'base64'
require 'openssl'

session_secret_base64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = Base64.decode64(session_secret_base64)

auth_code_payload = 'AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU'

hmac = OpenSSL::HMAC.digest(
  'sha256', session_secret, auth_code_payload
)
auth_code = Base64.urlsafe_encode64(hmac).sub(/=*$/, '')

puts auth_code
Example 6. authCode parameter
AtayuRPP3N59wXF8Cijwjt3pQ16knW2L-5VLDTRD_KU
IMPORTANT

If QR flow is used, the initialCallbackUrl is empty and the field must be included as an empty byte array.

  • Authentication Session

  • Signature Session

  • Certificate-choice Session

For authentication session device links signatureProtocol value is ACSP_V2:

authCodePayload := UTF8-ENCODE(STR-CONCAT(
        'smart-id', '|',
        'ACSP_V2', '|',
        rpChallenge, '|',
        BASE64-ENCODE(relyingPartyName), '|',
        BASE64-ENCODE(brokeredRpName), '|',
        interactions, '|',
        '', '|',
        unprotectedDeviceLink))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class AuthCodePayload {

  public static void main(String[] args) throws Exception {
    String separator = "|";
    String schemeName = "smart-id";
    String signatureProtocol = "ACSP_V2";
    String rpChallenge = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==";
    String relyingPartyNameBase64 = "REVNTw==";
    String brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
    String interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    String initialCallbackUrl = "";
    String unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    String[] payloadParts = {
      schemeName,
      signatureProtocol,
      rpChallenge,
      relyingPartyNameBase64,
      brokeredRpNameBase64,
      interactions,
      initialCallbackUrl,
      unprotectedDeviceLink
    };

    String authCodePayload = String.join(separator, payloadParts);
    System.out.println(authCodePayload);
  }
}
<?php

$separator = '|';

$schemeName = 'smart-id';
$signatureProtocol = 'ACSP_V2';
$rpChallenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==';
$relyingPartyNameBase64 = 'REVNTw==';
$brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
$interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
$initialCallbackUrl = '';
$unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

$authCodePayload = implode($separator, [
    $schemeName,
    $signatureProtocol,
    $rpChallenge,
    $relyingPartyNameBase64,
    $brokeredRpNameBase64,
    $interactions,
    $initialCallbackUrl,
    $unprotectedDeviceLink
]);

echo $authCodePayload;

?>
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'ACSP_V2'
rp_challenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = ''
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = separator.join([
    scheme_name,
    signature_protocol,
    rp_challenge,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
])

print(auth_code_payload)
package main

import (
	"fmt"
)

func main() {
	var separator string = "|"

	var schemeName string = "smart-id"
	var signatureProtocol string = "ACSP_V2"
	var rpChallenge string = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=="
	var relyingPartyNameBase64 string = "REVNTw=="
	var brokeredRpNameBase64 string = "RXhhbXBsZSBSUA=="
	var interactions string = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
	var initialCallbackUrl string = ""
	var unprotectedDeviceLink string = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

	var payloadParts = []string{
		schemeName,
		signatureProtocol,
		rpChallenge,
		relyingPartyNameBase64,
		brokeredRpNameBase64,
		interactions,
		initialCallbackUrl,
		unprotectedDeviceLink,
	}

	var authCodePayload string = strings.Join(payloadParts, separator)

	fmt.Printf("%q\n", authCodePayload)
}
fn main() {
    let separator: &str = "|";
    let scheme_name: &str = "smart-id";
    let signature_protocol: &str = "ACSP_V2";
    let rp_challenge: &str = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==";
    let relying_party_name_base64: &str = "REVNTw==";
    let brokered_rp_name_base64: &str = "RXhhbXBsZSBSUA==";
    let interactions: &str = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    let initial_callback_url: &str = "";
    let unprotected_device_link: &str = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    let auth_code_payload_parts: [&str; 7] = [
        scheme_name,
        signature_protocol,
        rp_challenge,
        relying_party_name_base64,
        brokered_rp_name_base64,
        interactions,
        initial_callback_url,
        unprotected_device_link
    ];

    let auth_code_payload: String = auth_code_payload_parts.join(separator);

    println!("{}", auth_code_payload)
}
fun main() {
    val separator: String = "|"

    val schemeName: String = "smart-id"
    val signatureProtocol: String = "ACSP_V2"
    val rpChallenge: String = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=="
    val relyingPartyNameBase64: String = "REVNTw=="
    val brokeredRpNameBase64: String = "RXhhbXBsZSBSUA=="
    val interactions: String = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
    val initialCallbackUrl: String = ""
    val unprotectedDeviceLink: String = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

    val payloadParts: List<String> = listOf(
        schemeName,
        signatureProtocol,
        rpChallenge,
        relyingPartyNameBase64,
        brokeredRpNameBase64,
        interactions,
        initialCallbackUrl,
        unprotectedDeviceLink
    )

    val authCodePayload: String = payloadParts.joinToString(separator)

    println(authCodePayload)
}
using System;

public class AuthCodePayload
{
    public static void Main()
    {
        string separator = "|";

        string schemeName = "smart-id";
        string signatureProtocol = "ACSP_V2";
        string rpChallenge = "GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==";
        string relyingPartyNameBase64 = "REVNTw==";
        string brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
        string interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
        string initialCallbackUrl = "";
        string unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

        string[] payloadParts = {
            schemeName,
            signatureProtocol,
            rpChallenge,
            relyingPartyNameBase64,
            brokeredRpNameBase64,
            interactions,
            initialCallbackUrl,
            unprotectedDeviceLink
        };

        string authCodePayload = string.Join(separator, payloadParts);
        Console.WriteLine(authCodePayload);
    }
}
const separator = '|';

const schemeName = 'smart-id';
const signatureProtocol = 'ACSP_V2';
const rpChallenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==';
const relyingPartyNameBase64 = 'REVNTw==';
const brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
const interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
const initialCallbackUrl = '';
const unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

const authCodePayload = [
    schemeName,
    signatureProtocol,
    rpChallenge,
    relyingPartyNameBase64,
    brokeredRpNameBase64,
    interactions,
    initialCallbackUrl,
    unprotectedDeviceLink
].join(separator);

console.log(authCodePayload);
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'ACSP_V2'
rp_challenge = 'GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = ''
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = [
    scheme_name,
    signature_protocol,
    rp_challenge,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
].join(separator)

puts auth_code_payload

For signature session device links digest value replaces the rpChallenge, and signatureProtocol value is RAW_DIGEST_SIGNATURE:

authCodePayload := UTF8-ENCODE(STR-CONCAT(
        'smart-id', '|',
        'RAW_DIGEST_SIGNATURE', '|',
        digest, '|',
        BASE64-ENCODE(relyingPartyName), '|',
        BASE64-ENCODE(brokeredRpName), '|',
        interactions, '|',
        '', '|',
        unprotectedDeviceLink))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class AuthCodePayload {

  public static void main(String[] args) throws Exception {
    String separator = "|";
    String schemeName = "smart-id";
    String signatureProtocol = "RAW_DIGEST_SIGNATURE";
    String digest = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==";
    String relyingPartyNameBase64 = "REVNTw==";
    String brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
    String interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    String initialCallbackUrl = "";
    String unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    String[] payloadParts = {
      schemeName,
      signatureProtocol,
      digest,
      relyingPartyNameBase64,
      brokeredRpNameBase64,
      interactions,
      initialCallbackUrl,
      unprotectedDeviceLink
    };

    String authCodePayload = String.join(separator, payloadParts);
    System.out.println(authCodePayload);
  }
}
<?php

$separator = '|';

$schemeName = 'smart-id';
$signatureProtocol = 'RAW_DIGEST_SIGNATURE';
$digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==';
$relyingPartyNameBase64 = 'REVNTw==';
$brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
$interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
$initialCallbackUrl = '';
$unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

$authCodePayload = implode($separator, [
    $schemeName,
    $signatureProtocol,
    $digest,
    $relyingPartyNameBase64,
    $brokeredRpNameBase64,
    $interactions,
    $initialCallbackUrl,
    $unprotectedDeviceLink
]);

echo $authCodePayload;

?>
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'RAW_DIGEST_SIGNATURE'
digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = ''
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = separator.join([
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
])

print(auth_code_payload)
package main

import (
	"fmt"
)

func main() {
	var separator string = "|"

	var schemeName string = "smart-id"
	var signatureProtocol string = "RAW_DIGEST_SIGNATURE"
	var digest string = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=="
	var relyingPartyNameBase64 string = "REVNTw=="
	var brokeredRpNameBase64 string = "RXhhbXBsZSBSUA=="
	var interactions string = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
	var initialCallbackUrl string = ""
	var unprotectedDeviceLink string = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

	var payloadParts = []string{
		schemeName,
		signatureProtocol,
		digest,
		relyingPartyNameBase64,
		brokeredRpNameBase64,
		interactions,
		initialCallbackUrl,
		unprotectedDeviceLink,
	}

	var authCodePayload string = strings.Join(payloadParts, separator)

	fmt.Printf("%q\n", authCodePayload)
}
fn main() {
    let separator: &str = "|";
    let scheme_name: &str = "smart-id";
    let signature_protocol: &str = "RAW_DIGEST_SIGNATURE";
    let digest: &str = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==";
    let relying_party_name_base64: &str = "REVNTw==";
    let brokered_rp_name_base64: &str = "RXhhbXBsZSBSUA==";
    let interactions: &str = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
    let initial_callback_url: &str = "";
    let unprotected_device_link: &str = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    let auth_code_payload_parts: [&str; 7] = [
        scheme_name,
        signature_protocol,
        digest,
        relying_party_name_base64,
        brokered_rp_name_base64,
        interactions,
        initial_callback_url,
        unprotected_device_link
    ];

    let auth_code_payload: String = auth_code_payload_parts.join(separator);

    println!("{}", auth_code_payload)
}
fun main() {
    val separator: String = "|"

    val schemeName: String = "smart-id"
    val signatureProtocol: String = "RAW_DIGEST_SIGNATURE"
    val digest: String = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=="
    val relyingPartyNameBase64: String = "REVNTw=="
    val brokeredRpNameBase64: String = "RXhhbXBsZSBSUA=="
    val interactions: String = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d"
    val initialCallbackUrl: String = ""
    val unprotectedDeviceLink: String = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

    val payloadParts: List<String> = listOf(
        schemeName,
        signatureProtocol,
        digest,
        relyingPartyNameBase64,
        brokeredRpNameBase64,
        interactions,
        initialCallbackUrl,
        unprotectedDeviceLink
    )

    val authCodePayload: String = payloadParts.joinToString(separator)

    println(authCodePayload)
}
using System;

public class AuthCodePayload
{
    public static void Main()
    {
        string separator = "|";

        string schemeName = "smart-id";
        string signatureProtocol = "RAW_DIGEST_SIGNATURE";
        string digest = "FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==";
        string relyingPartyNameBase64 = "REVNTw==";
        string brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
        string interactions = "W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d";
        string initialCallbackUrl = "";
        string unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

        string[] payloadParts = {
            schemeName,
            signatureProtocol,
            digest,
            relyingPartyNameBase64,
            brokeredRpNameBase64,
            interactions,
            initialCallbackUrl,
            unprotectedDeviceLink
        };

        string authCodePayload = string.Join(separator, payloadParts);
        Console.WriteLine(authCodePayload);
    }
}
const separator = '|';

const schemeName = 'smart-id';
const signatureProtocol = 'RAW_DIGEST_SIGNATURE';
const digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==';
const relyingPartyNameBase64 = 'REVNTw==';
const brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
const interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d';
const initialCallbackUrl = '';
const unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

const authCodePayload = [
    schemeName,
    signatureProtocol,
    digest,
    relyingPartyNameBase64,
    brokeredRpNameBase64,
    interactions,
    initialCallbackUrl,
    unprotectedDeviceLink
].join(separator);

console.log(authCodePayload);
separator = '|'

scheme_name = 'smart-id'
signature_protocol = 'RAW_DIGEST_SIGNATURE'
digest = 'FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ=='
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = 'W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d'
initial_callback_url = ''
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = [
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
].join(separator)

puts auth_code_payload

For certificate-choice session device links, digest, interactions and signatureProtocol values are omitted:

authCodePayload := UTF8-ENCODE(STR-CONCAT(
        'smart-id', '|',
        '', '|',
        '', '|',
        BASE64-ENCODE(relyingPartyName), '|',
        BASE64-ENCODE(brokeredRpName), '|',
        '', '|',
        '', '|',
        unprotectedDeviceLink))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class AuthCodePayload {

  public static void main(String[] args) throws Exception {
    String separator = "|";
    String schemeName = "smart-id";
    String signatureProtocol = "";
    String digest = "";
    String relyingPartyNameBase64 = "REVNTw==";
    String brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
    String interactions = "";
    String initialCallbackUrl = "";
    String unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    String[] payloadParts = {
      schemeName,
      signatureProtocol,
      digest,
      relyingPartyNameBase64,
      brokeredRpNameBase64,
      interactions,
      initialCallbackUrl,
      unprotectedDeviceLink
    };

    String authCodePayload = String.join(separator, payloadParts);
    System.out.println(authCodePayload);
  }
}
<?php

$separator = '|';

$schemeName = 'smart-id';
$signatureProtocol = '';
$digest = '';
$relyingPartyNameBase64 = 'REVNTw==';
$brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
$interactions = '';
$initialCallbackUrl = '';
$unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

$authCodePayload = implode($separator, [
    $schemeName,
    $signatureProtocol,
    $digest,
    $relyingPartyNameBase64,
    $brokeredRpNameBase64,
    $interactions,
    $initialCallbackUrl,
    $unprotectedDeviceLink
]);

echo $authCodePayload;

?>
separator = '|'

scheme_name = 'smart-id'
signature_protocol = ''
digest = ''
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = ''
initial_callback_url = ''
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = separator.join([
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
])

print(auth_code_payload)
package main

import (
	"fmt"
)

func main() {
	var separator string = "|"

	var schemeName string = "smart-id"
	var signatureProtocol string = ""
	var digest string = ""
	var relyingPartyNameBase64 string = "REVNTw=="
	var brokeredRpNameBase64 string = "RXhhbXBsZSBSUA=="
	var interactions string = ""
	var initialCallbackUrl string = ""
	var unprotectedDeviceLink string = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

	var payloadParts = []string{
		schemeName,
		signatureProtocol,
		digest,
		relyingPartyNameBase64,
		brokeredRpNameBase64,
		interactions,
		initialCallbackUrl,
		unprotectedDeviceLink,
	}

	var authCodePayload string = strings.Join(payloadParts, separator)

	fmt.Printf("%q\n", authCodePayload)
}
fn main() {
    let separator: &str = "|";
    let scheme_name: &str = "smart-id";
    let signature_protocol: &str = "";
    let digest: &str = "";
    let relying_party_name_base64: &str = "REVNTw==";
    let brokered_rp_name_base64: &str = "RXhhbXBsZSBSUA==";
    let interactions: &str = "";
    let initial_callback_url: &str = "";
    let unprotected_device_link: &str = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

    let auth_code_payload_parts: [&str; 7] = [
        scheme_name,
        signature_protocol,
        digest,
        relying_party_name_base64,
        brokered_rp_name_base64,
        interactions,
        initial_callback_url,
        unprotected_device_link
    ];

    let auth_code_payload: String = auth_code_payload_parts.join(separator);

    println!("{}", auth_code_payload)
}
fun main() {
    val separator: String = "|"

    val schemeName: String = "smart-id"
    val signatureProtocol: String = ""
    val digest: String = ""
    val relyingPartyNameBase64: String = "REVNTw=="
    val brokeredRpNameBase64: String = "RXhhbXBsZSBSUA=="
    val interactions: String = ""
    val initialCallbackUrl: String = ""
    val unprotectedDeviceLink: String = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng"

    val payloadParts: List<String> = listOf(
        schemeName,
        signatureProtocol,
        digest,
        relyingPartyNameBase64,
        brokeredRpNameBase64,
        interactions,
        initialCallbackUrl,
        unprotectedDeviceLink
    )

    val authCodePayload: String = payloadParts.joinToString(separator)

    println(authCodePayload)
}
using System;

public class AuthCodePayload
{
    public static void Main()
    {
        string separator = "|";

        string schemeName = "smart-id";
        string signatureProtocol = "";
        string digest = "";
        string relyingPartyNameBase64 = "REVNTw==";
        string brokeredRpNameBase64 = "RXhhbXBsZSBSUA==";
        string interactions = "";
        string initialCallbackUrl = "";
        string unprotectedDeviceLink = "https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng";

        string[] payloadParts = {
            schemeName,
            signatureProtocol,
            digest,
            relyingPartyNameBase64,
            brokeredRpNameBase64,
            interactions,
            initialCallbackUrl,
            unprotectedDeviceLink
        };

        string authCodePayload = string.Join(separator, payloadParts);
        Console.WriteLine(authCodePayload);
    }
}
const separator = '|';

const schemeName = 'smart-id';
const signatureProtocol = '';
const digest = '';
const relyingPartyNameBase64 = 'REVNTw==';
const brokeredRpNameBase64 = 'RXhhbXBsZSBSUA==';
const interactions = '';
const initialCallbackUrl = '';
const unprotectedDeviceLink = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng';

const authCodePayload = [
    schemeName,
    signatureProtocol,
    digest,
    relyingPartyNameBase64,
    brokeredRpNameBase64,
    interactions,
    initialCallbackUrl,
    unprotectedDeviceLink
].join(separator);

console.log(authCodePayload);
separator = '|'

scheme_name = 'smart-id'
signature_protocol = ''
digest = ''
relying_party_name_base64 = 'REVNTw=='
brokered_rp_name_base64 = 'RXhhbXBsZSBSUA=='
interactions = ''
initial_callback_url = ''
unprotected_device_link = 'https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng'

auth_code_payload = [
    scheme_name,
    signature_protocol,
    digest,
    relying_party_name_base64,
    brokered_rp_name_base64,
    interactions,
    initial_callback_url,
    unprotected_device_link
].join(separator)

puts auth_code_payload

After the RP assembles the authCodePayload, authCode can be calculated as follows:

  • Authentication Session

  • Signature Session

  • Certificate-choice Session

authCode := BASE64URL-ENCODE(HMAC-SHA256(sessionSecret, authCodePayload))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AuthCodeCalculator {

  public static void main(String[] args) throws Exception {
    String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

    byte[] sessionSecret = Base64.getDecoder()
      .decode(sessionSecretBase64);

    byte[] authCodePayload = "OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0"
      .getBytes(StandardCharsets.UTF_8);

    Mac sha256Hmac = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(sessionSecret, sha256Hmac.getAlgorithm());
    sha256Hmac.init(secretKey);

    byte[] authCodeBytes = sha256Hmac.doFinal(authCodePayload);

    String authCode = Base64.getUrlEncoder()
      .withoutPadding()
      .encodeToString(authCodeBytes);

    System.out.println(authCode);
  }
}
<?php

$sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
$sessionSecret = base64_decode($sessionSecretBase64);

$authCodePayload = 'OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0';

$authCodeBytes = hash_hmac('sha256', $authCodePayload, $sessionSecret, true);

$authCode = rtrim(strtr(base64_encode($authCodeBytes), '+/', '-_'), '=');

echo $authCode;
?>
import hmac
import hashlib
import base64

session_secret_base64 = b'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = base64.b64decode(session_secret_base64)

auth_code_payload = b'OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0'

auth_code_bytes = hmac.new(session_secret, auth_code_payload, hashlib.sha256).digest()

auth_code = base64.urlsafe_b64encode(auth_code_bytes).rstrip(b'=').decode('utf-8')
print(auth_code)
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
	var authCodePayload []byte = []byte("OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0")

	sessionSecret, err := base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	mac := hmac.New(sha256.New, sessionSecret)
	mac.Write(authCodePayload)
	var authCodeBytes []byte = mac.Sum(nil)

	var authCode string = base64.RawURLEncoding.EncodeToString(authCodeBytes)
	fmt.Printf("%s\n", authCode)
}
use hmac::{Hmac, Mac};
use sha2::Sha256;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret: &[u8] = &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();

    let auth_code_payload: &[u8] = &b"OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0"[..];

    let mut mac = Hmac::<Sha256>::new_from_slice(session_secret).expect("HMAC can take key of any size");
    mac.update(auth_code_payload);

    let auth_code_bytes = mac.finalize().into_bytes();

    const CUSTOM_ENGINE: engine::GeneralPurpose = base64::engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
    let auth_code: String = CUSTOM_ENGINE.encode(auth_code_bytes);
    println!("{}", auth_code)
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
  val sessionSecret: ByteArray = Base64.getDecoder()
    .decode(sessionSecretBase64)

  val authCodePayload: ByteArray = "OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0"
    .toByteArray(StandardCharsets.UTF_8)

  val hmac: Mac = Mac.getInstance("HmacSHA256")
  val secretKey: SecretKey = SecretKeySpec(sessionSecret, hmac.algorithm)
  hmac.init(secretKey)

  val authCodeBytes: ByteArray = hmac.doFinal(authCodePayload)

  val authCode: String = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(authCodeBytes)

  println(authCode)
}
using System;
using System.Text;
using System.Security.Cryptography;

public class AuthCodeCalculator
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecret = Convert.FromBase64String(sessionSecretBase64);
        byte[] authCodePayload = Encoding.UTF8.GetBytes("OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0");

        HMACSHA256 hmac = new HMACSHA256(sessionSecret);
        byte[] authCodeBytes = hmac.ComputeHash(authCodePayload);
        string authCode = Convert.ToBase64String(authCodeBytes)
            .Replace('+', '-')
            .Replace('/', '_')
            .TrimEnd('=');

        Console.WriteLine(authCode);
    }
}
const crypto = require('crypto');

const sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');

const authCodePayload = 'OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0';

const hmac = crypto.createHmac('sha256', sessionSecret);
hmac.update(authCodePayload);

const authCode = hmac.digest('base64url')
    .replace(/=+$/, '');

console.log(authCode);
require 'base64'
require 'openssl'

session_secret_base64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = Base64.decode64(session_secret_base64)

auth_code_payload = 'OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0'

hmac = OpenSSL::HMAC.digest(
  'sha256', session_secret, auth_code_payload
)
auth_code = Base64.urlsafe_encode64(hmac).sub(/=*$/, '')

puts auth_code
Example 7. authCode parameter
OY1eHaD4UYedrBwtqUbSkpa0w7ttm4FllPkCD_3wlE0
authCode := BASE64URL-ENCODE(HMAC-SHA256(sessionSecret, authCodePayload))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AuthCodeCalculator {

  public static void main(String[] args) throws Exception {
    String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

    byte[] sessionSecret = Base64.getDecoder()
      .decode(sessionSecretBase64);

    byte[] authCodePayload = "5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco"
      .getBytes(StandardCharsets.UTF_8);

    Mac sha256Hmac = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(sessionSecret, sha256Hmac.getAlgorithm());
    sha256Hmac.init(secretKey);

    byte[] authCodeBytes = sha256Hmac.doFinal(authCodePayload);

    String authCode = Base64.getUrlEncoder()
      .withoutPadding()
      .encodeToString(authCodeBytes);

    System.out.println(authCode);
  }
}
<?php

$sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
$sessionSecret = base64_decode($sessionSecretBase64);

$authCodePayload = '5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco';

$authCodeBytes = hash_hmac('sha256', $authCodePayload, $sessionSecret, true);

$authCode = rtrim(strtr(base64_encode($authCodeBytes), '+/', '-_'), '=');

echo $authCode;
?>
import hmac
import hashlib
import base64

session_secret_base64 = b'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = base64.b64decode(session_secret_base64)

auth_code_payload = b'5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco'

auth_code_bytes = hmac.new(session_secret, auth_code_payload, hashlib.sha256).digest()

auth_code = base64.urlsafe_b64encode(auth_code_bytes).rstrip(b'=').decode('utf-8')
print(auth_code)
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
	var authCodePayload []byte = []byte("5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco")

	sessionSecret, err := base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	mac := hmac.New(sha256.New, sessionSecret)
	mac.Write(authCodePayload)
	var authCodeBytes []byte = mac.Sum(nil)

	var authCode string = base64.RawURLEncoding.EncodeToString(authCodeBytes)
	fmt.Printf("%s\n", authCode)
}
use hmac::{Hmac, Mac};
use sha2::Sha256;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret: &[u8] = &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();

    let auth_code_payload: &[u8] = &b"5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco"[..];

    let mut mac = Hmac::<Sha256>::new_from_slice(session_secret).expect("HMAC can take key of any size");
    mac.update(auth_code_payload);

    let auth_code_bytes = mac.finalize().into_bytes();

    const CUSTOM_ENGINE: engine::GeneralPurpose = base64::engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
    let auth_code: String = CUSTOM_ENGINE.encode(auth_code_bytes);
    println!("{}", auth_code)
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
  val sessionSecret: ByteArray = Base64.getDecoder()
    .decode(sessionSecretBase64)

  val authCodePayload: ByteArray = "5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco"
    .toByteArray(StandardCharsets.UTF_8)

  val hmac: Mac = Mac.getInstance("HmacSHA256")
  val secretKey: SecretKey = SecretKeySpec(sessionSecret, hmac.algorithm)
  hmac.init(secretKey)

  val authCodeBytes: ByteArray = hmac.doFinal(authCodePayload)

  val authCode: String = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(authCodeBytes)

  println(authCode)
}
using System;
using System.Text;
using System.Security.Cryptography;

public class AuthCodeCalculator
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecret = Convert.FromBase64String(sessionSecretBase64);
        byte[] authCodePayload = Encoding.UTF8.GetBytes("5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco");

        HMACSHA256 hmac = new HMACSHA256(sessionSecret);
        byte[] authCodeBytes = hmac.ComputeHash(authCodePayload);
        string authCode = Convert.ToBase64String(authCodeBytes)
            .Replace('+', '-')
            .Replace('/', '_')
            .TrimEnd('=');

        Console.WriteLine(authCode);
    }
}
const crypto = require('crypto');

const sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');

const authCodePayload = '5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco';

const hmac = crypto.createHmac('sha256', sessionSecret);
hmac.update(authCodePayload);

const authCode = hmac.digest('base64url')
    .replace(/=+$/, '');

console.log(authCode);
require 'base64'
require 'openssl'

session_secret_base64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = Base64.decode64(session_secret_base64)

auth_code_payload = '5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco'

hmac = OpenSSL::HMAC.digest(
  'sha256', session_secret, auth_code_payload
)
auth_code = Base64.urlsafe_encode64(hmac).sub(/=*$/, '')

puts auth_code
Example 8. authCode parameter
5PZVhiNDTnt1MjLz8_YCjnNtR7p0iGevaL2G1ajfMco
authCode := BASE64URL-ENCODE(HMAC-SHA256(sessionSecret, authCodePayload))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AuthCodeCalculator {

  public static void main(String[] args) throws Exception {
    String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

    byte[] sessionSecret = Base64.getDecoder()
      .decode(sessionSecretBase64);

    byte[] authCodePayload = "T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo"
      .getBytes(StandardCharsets.UTF_8);

    Mac sha256Hmac = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(sessionSecret, sha256Hmac.getAlgorithm());
    sha256Hmac.init(secretKey);

    byte[] authCodeBytes = sha256Hmac.doFinal(authCodePayload);

    String authCode = Base64.getUrlEncoder()
      .withoutPadding()
      .encodeToString(authCodeBytes);

    System.out.println(authCode);
  }
}
<?php

$sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
$sessionSecret = base64_decode($sessionSecretBase64);

$authCodePayload = 'T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo';

$authCodeBytes = hash_hmac('sha256', $authCodePayload, $sessionSecret, true);

$authCode = rtrim(strtr(base64_encode($authCodeBytes), '+/', '-_'), '=');

echo $authCode;
?>
import hmac
import hashlib
import base64

session_secret_base64 = b'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = base64.b64decode(session_secret_base64)

auth_code_payload = b'T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo'

auth_code_bytes = hmac.new(session_secret, auth_code_payload, hashlib.sha256).digest()

auth_code = base64.urlsafe_b64encode(auth_code_bytes).rstrip(b'=').decode('utf-8')
print(auth_code)
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
	var authCodePayload []byte = []byte("T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo")

	sessionSecret, err := base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	mac := hmac.New(sha256.New, sessionSecret)
	mac.Write(authCodePayload)
	var authCodeBytes []byte = mac.Sum(nil)

	var authCode string = base64.RawURLEncoding.EncodeToString(authCodeBytes)
	fmt.Printf("%s\n", authCode)
}
use hmac::{Hmac, Mac};
use sha2::Sha256;
use base64::{Engine as _, engine::{self, general_purpose}, alphabet};

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret: &[u8] = &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();

    let auth_code_payload: &[u8] = &b"T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo"[..];

    let mut mac = Hmac::<Sha256>::new_from_slice(session_secret).expect("HMAC can take key of any size");
    mac.update(auth_code_payload);

    let auth_code_bytes = mac.finalize().into_bytes();

    const CUSTOM_ENGINE: engine::GeneralPurpose = base64::engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
    let auth_code: String = CUSTOM_ENGINE.encode(auth_code_bytes);
    println!("{}", auth_code)
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets
import java.util.Base64

fun main() {
  val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
  val sessionSecret: ByteArray = Base64.getDecoder()
    .decode(sessionSecretBase64)

  val authCodePayload: ByteArray = "T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo"
    .toByteArray(StandardCharsets.UTF_8)

  val hmac: Mac = Mac.getInstance("HmacSHA256")
  val secretKey: SecretKey = SecretKeySpec(sessionSecret, hmac.algorithm)
  hmac.init(secretKey)

  val authCodeBytes: ByteArray = hmac.doFinal(authCodePayload)

  val authCode: String = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(authCodeBytes)

  println(authCode)
}
using System;
using System.Text;
using System.Security.Cryptography;

public class AuthCodeCalculator
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecret = Convert.FromBase64String(sessionSecretBase64);
        byte[] authCodePayload = Encoding.UTF8.GetBytes("T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo");

        HMACSHA256 hmac = new HMACSHA256(sessionSecret);
        byte[] authCodeBytes = hmac.ComputeHash(authCodePayload);
        string authCode = Convert.ToBase64String(authCodeBytes)
            .Replace('+', '-')
            .Replace('/', '_')
            .TrimEnd('=');

        Console.WriteLine(authCode);
    }
}
const crypto = require('crypto');

const sessionSecretBase64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=';
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');

const authCodePayload = 'T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo';

const hmac = crypto.createHmac('sha256', sessionSecret);
hmac.update(authCodePayload);

const authCode = hmac.digest('base64url')
    .replace(/=+$/, '');

console.log(authCode);
require 'base64'
require 'openssl'

session_secret_base64 = 'B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps='
session_secret = Base64.decode64(session_secret_base64)

auth_code_payload = 'T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo'

hmac = OpenSSL::HMAC.digest(
  'sha256', session_secret, auth_code_payload
)
auth_code = Base64.urlsafe_encode64(hmac).sub(/=*$/, '')

puts auth_code
Example 9. authCode parameter
T5pDDPAjoMS0byqS-FoaWVjlubODXoCCF4XDB4HeYNo

Parameters in authCode

The parameters included in the authCode calculation are explained below:

Parameter Formula

sessionSecret

Generated by RP API. Used as the key in authCode calculation. Must be Base64 decoded before use.

schemeName

Scheme name is defined by Smart-ID service and it ties the link to the Smart-ID context. The schemeName value depends on the environment. See Environments page for concrete values.

signatureProtocol

Allowed values:

  • ACSP_V2 - for authentication session,

  • RAW_DIGEST_SIGNATURE - for signature session,

  • empty - for certificate-choice session.

rpChallenge

rpChallenge used in the initial authentication request. For more details, see ACSP_V2 signature request parameters.

digest

digest used in the initial signature request. For more details, see RAW_DIGEST_SIGNATURE signature request parameters.

relyingPartyName

relyingPartyName used in the initial authentication or signature requests in Base64 encoded form.

brokeredRpName

brokeredRpName used in the initial authentication or signature requests in Base64 encoded form. This is only used by those RPs that act as a broker for other RPs. Otherwise must be empty.

interactions

interactions used in the initial authentication or signature request in Base64 encoded form. Empty for certificate-choice session request. Since JSON to Base64 encoding is non-deterministic (parameters may be ordered randomly, whitespace can be optional), the specific Base64-encoded string generated from the interactions object to initiate the session must be reused here in order to guarantee that the values match exactly.

initialCallbackUrl

Callback URL the Smart-ID app will add parameters to and launch after a successful signature has been given (only in Web2App and App2App flows). Must use HTTPS scheme and there must not be URL fragments (#) in the URL.

unprotectedDeviceLink

The final URL without the authCode field. Including this in authCode calculation ensures that the link itself can’t be changed by any malicious party.

sessionSecret parameter

RP API returns sessionSecret in Base64 encoded form. The Base64 string value must be decoded into a byte array before use:

sessionSecret := BASE64-DECODE(sessionSecret)
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.util.Base64;

public class Base64Decode {

    public static void main(String[] args) {
        String sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";

        byte[] sessionSecretBytes =
        Base64.getDecoder().decode(
            sessionSecretBase64
        );
    }
}
<?php

$sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
$sessionSecret = base64_decode($sessionSecretBase64);

?>
import base64

session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
session_secret_bytes = base64.b64decode(session_secret_base64)
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	var sessionSecretBase64 string = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="

	var sessionSecretBytes, err =
		base64.StdEncoding.DecodeString(sessionSecretBase64)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%q\n", sessionSecretBytes)
}
use base64::Engine as _;

fn main() {
    let session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
    let session_secret_bytes: &[u8] =
      &base64::engine::general_purpose::STANDARD.decode(session_secret_base64).unwrap();
}
import java.util.Base64

fun main() {
    val sessionSecretBase64: String = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
    val sessionSecretBytes: ByteArray =
        Base64.getDecoder().decode(sessionSecretBase64)
}
using System;

public class Base64Decode
{
    public static void Main(string[] args)
    {
        string sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
        byte[] sessionSecretBytes = Convert.FromBase64String(sessionSecretBase64);
    }
}
const sessionSecretBase64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=";
const sessionSecret = Buffer.from(sessionSecretBase64, 'base64');
require 'base64'

session_secret_base64 = "B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps="
session_secret = Base64.decode64(session_secret_base64)
Example 10. sessionSecret parameter
B98ODiVCebRedSwdTk51zFSaGYyHtY1H2A0ocAi3/Ps=

schemeName parameter

Scheme name that ties the link to the Smart-ID context. The schemeName value depends on the environment. See Environments page for concrete values.

Example 11. schemeName parameter
smart-id

signatureProtocol parameter

The same signatureProtocol value that was sent in the initial authentication or signature request. Currently, the only allowed types are:

  • ACSP_V2 for authentication,

  • RAW_DIGEST_SIGNATURE for signature requests,

  • empty - for certificate-choice session.

Example 12. signatureProtocol parameter
ACSP_V2

rpChallenge or digest parameter

The same rpChallenge value or digest value that was sent in the initial authentication or signature request, respectively. This value must be empty for certificate-choice session request.

rpChallenge and digest parameters are sent to RP API by RPs in Base64 encoded form. They must be used in Base64 form.

Example 13. rpChallenge parameter
GYS+yoah6emAcVDNIajwSs6UB/M95XrDxMzXBUkwQJ9YFDipXXzGpPc7raWcuc2+TEoRc7WvIZ/7dU/iRXenYg==
Example 14. digest parameter
FNZFFya5wGLv9b27fZngaWrOBqle4tGwxZuDFRBdPl1RQvxJsfoqvTbjafd+8BcehMOQGvak6zlP+F8tga4bfQ==

relyingPartyName parameter

The parameter relyingPartyName describes the RP name as specified in the initial authentication, signature or certificate-choice request.

The string value must be UTF-8 encoded into a byte array and Base64 encoded before use in authCodePayload assembly:

relyingPartyName := BASE64-ENCODE(UTF8-ENCODE(relyingPartyName))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Base64Encode {

  public static void main(String[] args) {
    String relyingPartyName = "DEMO";
    String relyingPartyNameBase64 =
      Base64.getEncoder().encodeToString(
        relyingPartyName.getBytes(StandardCharsets.UTF_8)
      );

    System.out.println(relyingPartyNameBase64);
  }
}
<?php

$relyingPartyName = "DEMO";
$relyingPartyNameBase64 = base64_encode($relyingPartyName);
echo $relyingPartyNameBase64;

?>
import base64

relying_party_name = "DEMO"
relying_party_name_base64 = base64.b64encode(relying_party_name.encode('utf-8'))
print(relying_party_name_base64)
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	var relyingPartyName string = "DEMO"
	var relyingPartyNameBase64 []byte = []byte(base64.StdEncoding.EncodeToString([]byte(relyingPartyName)))
	fmt.Printf("%q\n", relyingPartyNameBase64)
}
use base64::Engine as _;

fn main() {
    let relying_party_name: &str = "DEMO";
    let relying_party_name_base64_string: String = base64::engine::general_purpose::STANDARD.encode(relying_party_name.as_bytes());
    let relying_party_name_base64: &[u8] = relying_party_name_base64_string.as_bytes();
    println!("{:?}\n{}", relying_party_name_base64, relying_party_name_base64_string);
}
import java.util.Base64

fun main() {
    val relyingPartyName: String = "DEMO"
    val relyingPartyNameBase64: String = Base64.getEncoder()
      .encodeToString(relyingPartyName.toByteArray(Charsets.UTF_8))
    println(relyingPartyNameBase64)
}
using System;
using System.Text;

public class Base64Encode
{
    public static void Main(string[] args)
    {
        string relyingPartyName = "DEMO";
        byte[] relyingPartyNameBytes =
            Encoding.UTF8.GetBytes(relyingPartyName);
        string relyingPartyNameBase64 =
            Convert.ToBase64String(relyingPartyNameBytes);

        Console.WriteLine(relyingPartyNameBase64);
    }
}
let relyingPartyName = 'DEMO';
let relyingPartyNameBase64 = Buffer.from(relyingPartyName, 'utf-8')
  .toString('base64');
console.log(relyingPartyNameBase64);
require 'base64'

relying_party_name = "DEMO"
relying_party_name_base64 = Base64.strict_encode64(relying_party_name.encode('UTF-8'))
puts relying_party_name_base64
Example 15. relyingPartyName parameter
REVNTw==

brokeredRpName parameter

The parameter brokeredRpName describes the RP name as specified in the initial authentication, signature or certificate-choice request. Must only be used by RPs that act as a broker and for other RPs otherwise must be empty.

The string value must be UTF-8 encoded into a byte array and Base64 encoded before use in authCodePayload assembly:

brokeredRpName := BASE64-ENCODE(UTF8-ENCODE(brokeredRpName))
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Base64Encode {

  public static void main(String[] args) {
    String brokeredRpName = "Example RP";
    String brokeredRpNameBase64 =
      Base64.getEncoder().encodeToString(
        brokeredRpName.getBytes(StandardCharsets.UTF_8)
      );

    System.out.println(brokeredRpNameBase64);
  }
}
<?php

$brokeredRpName = "Example RP";
$brokeredRpNameBase64 = base64_encode($brokeredRpName);
echo $brokeredRpNameBase64;

?>
import base64

brokered_rp_name = "Example RP"
brokered_rp_name_base64 = base64.b64encode(brokered_rp_name.encode('utf-8'))
print(brokered_rp_name_base64)
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	var brokeredRpName string = "Example RP"
	var brokeredRpNameBase64 []byte = []byte(base64.StdEncoding.EncodeToString([]byte(brokeredRpName)))
	fmt.Printf("%q\n", brokeredRpNameBase64)
}
use base64::Engine as _;

fn main() {
    let brokered_rp_name: &str = "Example RP";
    let brokered_rp_name_base64_string: String = base64::engine::general_purpose::STANDARD.encode(brokered_rp_name.as_bytes());
    let brokered_rp_name_base64: &[u8] = brokered_rp_name_base64_string.as_bytes();
    println!("{:?}\n{}", brokered_rp_name_base64, brokered_rp_name_base64_string);
}
import java.util.Base64

fun main() {
    val brokeredRpName: String = "Example RP"
    val brokeredRpNameBase64: String = Base64.getEncoder()
      .encodeToString(brokeredRpName.toByteArray(Charsets.UTF_8))
    println(brokeredRpNameBase64)
}
using System;
using System.Text;

public class Base64Encode
{
    public static void Main(string[] args)
    {
        string brokeredRpName = "Example RP";
        byte[] brokeredRpNameBytes =
            Encoding.UTF8.GetBytes(brokeredRpName);
        string brokeredRpNameBase64 =
            Convert.ToBase64String(brokeredRpNameBytes);

        Console.WriteLine(brokeredRpNameBase64);
    }
}
let brokeredRpName = 'Example RP';
let brokeredRpNameBase64 = Buffer.from(brokeredRpName, 'utf-8')
  .toString('base64');
console.log(brokeredRpNameBase64);
require 'base64'

brokered_rp_name = "Example RP"
brokered_rp_name_base64 = Base64.strict_encode64(brokered_rp_name.encode('UTF-8'))
puts brokered_rp_name_base64
Example 16. brokeredRpName parameter
RXhhbXBsZSBSUA==

interactions parameter

The parameter interactions as described in interactions section. Empty for certificate-choice session request.

Example 17. interactions parameter
W3sidHlwZSI6ImNvbmZpcm1hdGlvbk1lc3NhZ2UiLCJkaXNwbGF5VGV4dDIwMCI6IkxvbmdlciBkZXNjcmlwdGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gY29udGV4dCJ9LHsidHlwZSI6ImRpc3BsYXlUZXh0QW5kUElOIiwiZGlzcGxheVRleHQ2MCI6IlNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0In1d

initialCallbackUrl parameter

  • Web2App

  • App2App

  • QR

The initialCallbackUrl parameter specified by the RP in the initial request. Must use HTTPS scheme. Must not have URL fragments (#). In case of QR flows, must be empty. RPs must append a unique parameter to each session in the callback URL to make the URL unpredictable.

TIP

The Smart-ID app will launch the callback URL after a successful signature has been obtained in Web2App and App2App flows. For verifying the callback URL once the user successfully completes the flow, see Callback URLs page.

The string value must be UTF-8 encoded into a byte array before use in authCodePayload assembly:

initialCallbackUrl := UTF8-ENCODE(initialCallbackUrl)
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;

public class Utf8Encode {

    public static void main(String[] args) {
        String initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        byte[] initialCallbackUrlBytes = initialCallbackUrl.getBytes(StandardCharsets.UTF_8);
    }
}
<?php

$initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
$initialCallbackUrlBytes = mb_convert_encoding($initialCallbackUrl, 'UTF-8');

?>
initial_callback_url = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
initial_callback_url_bytes = initial_callback_url.encode('utf-8')
package main

import (
	"fmt"
)

func main() {
	var initialCallbackUrl string = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
	var initialCallbackUrlBytes []byte = []byte(initialCallbackUrl)

	fmt.Printf("%q\n", initialCallbackUrlBytes)
}
fn main() {
    let initial_callback_url: &str = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    let initial_callback_url_bytes: &[u8] = initial_callback_url.as_bytes();
}
import java.nio.charset.Charset

fun main() {
  val initialCallbackUrl: String = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
  val initialCallbackUrlBytes: ByteArray = initialCallbackUrl.toByteArray(Charsets.UTF_8)
}
using System.Text;

public class Utf8Encode
{
    public static void Main()
    {
        string initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        byte[] initialCallbackUrlBytes = Encoding.UTF8.GetBytes(initialCallbackUrl);
    }
}
let initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
let initialCallbackUrlBytes = Buffer.from(initialCallbackUrl, 'utf-8');
initial_callback_url = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
initial_callback_url_bytes = initial_callback_url.encode('UTF-8')
Example 18. initialCallbackUrl parameter
https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ

The initialCallbackUrl parameter specified by the RP in the initial request. Must use HTTPS scheme. Must not have URL fragments (#). In case of QR flows, must be empty. RPs must append a unique parameter to each session in the callback URL to make the URL unpredictable.

TIP

The Smart-ID app will launch the callback URL after a successful signature has been obtained in Web2App and App2App flows. For verifying the callback URL once the user successfully completes the flow, see Callback URLs page.

The string value must be UTF-8 encoded into a byte array before use in authCodePayload assembly:

initialCallbackUrl := UTF8-ENCODE(initialCallbackUrl)
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

import java.nio.charset.StandardCharsets;

public class Utf8Encode {

    public static void main(String[] args) {
        String initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        byte[] initialCallbackUrlBytes = initialCallbackUrl.getBytes(StandardCharsets.UTF_8);
    }
}
<?php

$initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
$initialCallbackUrlBytes = mb_convert_encoding($initialCallbackUrl, 'UTF-8');

?>
initial_callback_url = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
initial_callback_url_bytes = initial_callback_url.encode('utf-8')
package main

import (
	"fmt"
)

func main() {
	var initialCallbackUrl string = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
	var initialCallbackUrlBytes []byte = []byte(initialCallbackUrl)

	fmt.Printf("%q\n", initialCallbackUrlBytes)
}
fn main() {
    let initial_callback_url: &str = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
    let initial_callback_url_bytes: &[u8] = initial_callback_url.as_bytes();
}
import java.nio.charset.Charset

fun main() {
  val initialCallbackUrl: String = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
  val initialCallbackUrlBytes: ByteArray = initialCallbackUrl.toByteArray(Charsets.UTF_8)
}
using System.Text;

public class Utf8Encode
{
    public static void Main()
    {
        string initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
        byte[] initialCallbackUrlBytes = Encoding.UTF8.GetBytes(initialCallbackUrl);
    }
}
let initialCallbackUrl = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ";
let initialCallbackUrlBytes = Buffer.from(initialCallbackUrl, 'utf-8');
initial_callback_url = "https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ"
initial_callback_url_bytes = initial_callback_url.encode('UTF-8')
Example 19. initialCallbackUrl parameter
https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ

In case of QR flows, initialCallbackUrl must be empty.

  • Web2App

  • App2App

  • QR

The final device link URL without the authCode field. RP must use deviceLinkType = Web2App for flows that start from a browser, deviceLinkType = App2App for flows that start from an RP app, and deviceLinkType = QR for cross-device flows.

elapsedSeconds value must not be added for Web2App and App2App flows.

unprotectedDeviceLink must be assembled as follows to be used in authCodePayload calculation:

unprotectedDeviceLink := STR-CONCAT(
        deviceLinkBase, "?",
        "deviceLinkType=", deviceLinkType,
        "&sessionToken=", sessionToken,
        "&sessionType=", sessionType,
        "&version=", version,
        "&lang=", lang)
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class UnprotectedDeviceLink {

  public static void main(String[] args) {

    String deviceLinkBase = "https://smart-id.com";
    String deviceLinkType = "Web2App";
    String sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
    String sessionType = "auth";
    String version = "1.0";
    String lang = "eng";

    String unprotectedDeviceLink = deviceLinkBase + "?" +
      "deviceLinkType=" + deviceLinkType +
      "&sessionToken=" + sessionToken +
      "&sessionType=" + sessionType +
      "&version=" + version +
      "&lang=" + lang;

    System.out.println(unprotectedDeviceLink);
  }
}
<?php

$deviceLinkBase = "https://smart-id.com";
$deviceLinkType = "Web2App";
$sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
$sessionType = "auth";
$version = "1.0";
$lang = "eng";

$unprotectedDeviceLink = $deviceLinkBase . "?" .
'deviceLinkType=' . $deviceLinkType .
'&sessionToken=' . $sessionToken .
'&sessionType=' . $sessionType .
'&version=' . $version .
'&lang=' . $lang;

echo $unprotectedDeviceLink . PHP_EOL;

?>
device_link_base = "https://smart-id.com"
device_link_type = "Web2App" # One of "Web2App", "App2App", "QR"
session_token = "wGIrqveE6AuGDATZKmR1mtAZ"
session_type = "auth"
version = "1.0"
lang = "eng"
unprotected_device_link = device_link_base + "?" + \
  "deviceLinkType=" + device_link_type + \
  "&sessionToken=" + session_token + \
  "&sessionType=" + session_type + \
  "&version=" + version + \
  "&lang=" + lang

print(unprotected_device_link)
package main

import (
	"fmt"
	"strconv"
)

func main() {
	var deviceLinkBase string = "https://smart-id.com"
	var deviceLinkType string = "Web2App" // One of "Web2App", "App2App", "QR"
	var sessionToken string = "wGIrqveE6AuGDATZKmR1mtAZ"
	var sessionType string = "auth"
	var version string = "1.0"
	var lang string = "eng"

	var unprotectedDeviceLink string = deviceLinkBase + "?" +
		"deviceLinkType=" + deviceLinkType +
		"&sessionToken=" + sessionToken +
		"&sessionType=" + sessionType +
		"&version=" + version +
		"&lang=" + lang

	fmt.Printf("%q\n", unprotectedDeviceLink)
}
fn main() {
    let device_link_base: &str = "https://smart-id.com";
    let device_link_type: &str = "Web2App"; // One of "Web2App", "App2App", "QR"
    let session_token: &str = "wGIrqveE6AuGDATZKmR1mtAZ";
    let session_type: &str = "auth";
    let version: &str = "1.0";
    let lang: &str = "eng";

    let unprotected_device_link: String = format!("{}?deviceLinkType={}&sessionToken={}&sessionType={}&version={}&lang={}", device_link_base, device_link_type, session_token, session_type, version, lang);

    println!("{}", unprotected_device_link);
}
package main

fun main() {
    val deviceLinkBase: String = "https://smart-id.com"
    val deviceLinkType: String = "Web2App"
    val sessionToken: String = "wGIrqveE6AuGDATZKmR1mtAZ"
    val sessionType: String = "auth"
    val version: String = "1.0"
    val lang: String = "eng"

    val unprotectedDeviceLink: String = "$deviceLinkBase" + "?" +
      "deviceLinkType=$deviceLinkType" +
      "&sessionToken=$sessionToken" +
      "&sessionType=$sessionType" +
      "&version=$version" +
      "&lang=$lang"

    println(unprotectedDeviceLink)
}
using System;

public class UnprotectedDeviceLink
{
    public static void Main(string[] args)
    {
        string deviceLinkBase = "https://smart-id.com";
        string deviceLinkType = "Web2App";
        string sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
        string sessionType = "auth";
        string version = "1.0";
        string lang = "eng";

        string unprotectedDeviceLink = deviceLinkBase + "?" +
          "deviceLinkType=" + deviceLinkType +
          "&sessionToken=" + sessionToken +
          "&sessionType=" + sessionType +
          "&version=" + version +
          "&lang=" + lang;

        Console.WriteLine(unprotectedDeviceLink);
    }
}
const deviceLinkBase = "https://smart-id.com";
const deviceLinkType = "Web2App";
const sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
const sessionType = "auth";
const version = "1.0";
const lang = "eng";

const unprotectedDeviceLink = deviceLinkBase + '?' +
  'deviceLinkType=' + deviceLinkType +
  '&sessionToken=' + sessionToken +
  '&sessionType=' + sessionType +
  '&version=' + version +
  '&lang=' + lang;

console.log(unprotectedDeviceLink);
device_link_base = "https://smart-id.com"
device_link_type = "Web2App" # One of "Web2App", "App2App", "QR"
session_token = "wGIrqveE6AuGDATZKmR1mtAZ"
session_type = "auth"
version = "1.0"
lang = "eng"

unprotected_device_link = device_link_base + "?" +
  "deviceLinkType=" + device_link_type +
  "&sessionToken=" + session_token +
  "&sessionType=" + session_type +
  "&version=" + version +
  "&lang=" + lang

puts unprotected_device_link
Example 20. unprotectedDeviceLink parameter (Web2App authentication)
https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng
Example 21. unprotectedDeviceLink parameter (Web2App signature)
https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=sign&version=1.0&lang=eng
Example 22. unprotectedDeviceLink parameter (Web2App certificate-choice)
https://smart-id.com/device-link?deviceLinkType=Web2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=cert&version=1.0&lang=eng

The final device link URL without the authCode field. RP must use deviceLinkType = Web2App for flows that start from a browser, deviceLinkType = App2App for flows that start from an RP app, and deviceLinkType = QR for cross-device flows.

elapsedSeconds value must not be added for Web2App and App2App flows.

unprotectedDeviceLink must be assembled as follows to be used in authCodePayload calculation:

unprotectedDeviceLink := STR-CONCAT(
        deviceLinkBase, "?",
        "deviceLinkType=", deviceLinkType,
        "&sessionToken=", sessionToken,
        "&sessionType=", sessionType,
        "&version=", version,
        "&lang=", lang)
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class UnprotectedDeviceLink {

  public static void main(String[] args) {

    String deviceLinkBase = "https://smart-id.com";
    String deviceLinkType = "App2App";
    String sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
    String sessionType = "auth";
    String version = "1.0";
    String lang = "eng";

    String unprotectedDeviceLink = deviceLinkBase + "?" +
      "deviceLinkType=" + deviceLinkType +
      "&sessionToken=" + sessionToken +
      "&sessionType=" + sessionType +
      "&version=" + version +
      "&lang=" + lang;

    System.out.println(unprotectedDeviceLink);
  }
}
<?php

$deviceLinkBase = "https://smart-id.com";
$deviceLinkType = "App2App";
$sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
$sessionType = "auth";
$version = "1.0";
$lang = "eng";

$unprotectedDeviceLink = $deviceLinkBase . "?" .
'deviceLinkType=' . $deviceLinkType .
'&sessionToken=' . $sessionToken .
'&sessionType=' . $sessionType .
'&version=' . $version .
'&lang=' . $lang;

echo $unprotectedDeviceLink . PHP_EOL;

?>
device_link_base = "https://smart-id.com"
device_link_type = "App2App" # One of "Web2App", "App2App", "QR"
session_token = "wGIrqveE6AuGDATZKmR1mtAZ"
session_type = "auth"
version = "1.0"
lang = "eng"
unprotected_device_link = device_link_base + "?" + \
  "deviceLinkType=" + device_link_type + \
  "&sessionToken=" + session_token + \
  "&sessionType=" + session_type + \
  "&version=" + version + \
  "&lang=" + lang

print(unprotected_device_link)
package main

import (
	"fmt"
	"strconv"
)

func main() {
	var deviceLinkBase string = "https://smart-id.com"
	var deviceLinkType string = "App2App" // One of "Web2App", "App2App", "QR"
	var sessionToken string = "wGIrqveE6AuGDATZKmR1mtAZ"
	var sessionType string = "auth"
	var version string = "1.0"
	var lang string = "eng"

	var unprotectedDeviceLink string = deviceLinkBase + "?" +
		"deviceLinkType=" + deviceLinkType +
		"&sessionToken=" + sessionToken +
		"&sessionType=" + sessionType +
		"&version=" + version +
		"&lang=" + lang

	fmt.Printf("%q\n", unprotectedDeviceLink)
}
fn main() {
    let device_link_base: &str = "https://smart-id.com";
    let device_link_type: &str = "App2App"; // One of "Web2App", "App2App", "QR"
    let session_token: &str = "wGIrqveE6AuGDATZKmR1mtAZ";
    let session_type: &str = "auth";
    let version: &str = "1.0";
    let lang: &str = "eng";

    let unprotected_device_link: String = format!("{}?deviceLinkType={}&sessionToken={}&sessionType={}&version={}&lang={}", device_link_base, device_link_type, session_token, session_type, version, lang);

    println!("{}", unprotected_device_link);
}
package main

fun main() {
    val deviceLinkBase: String = "https://smart-id.com"
    val deviceLinkType: String = "App2App"
    val sessionToken: String = "wGIrqveE6AuGDATZKmR1mtAZ"
    val sessionType: String = "auth"
    val version: String = "1.0"
    val lang: String = "eng"

    val unprotectedDeviceLink: String = "$deviceLinkBase" + "?" +
      "deviceLinkType=$deviceLinkType" +
      "&sessionToken=$sessionToken" +
      "&sessionType=$sessionType" +
      "&version=$version" +
      "&lang=$lang"

    println(unprotectedDeviceLink)
}
using System;

public class UnprotectedDeviceLink
{
    public static void Main(string[] args)
    {
        string deviceLinkBase = "https://smart-id.com";
        string deviceLinkType = "App2App";
        string sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
        string sessionType = "auth";
        string version = "1.0";
        string lang = "eng";

        string unprotectedDeviceLink = deviceLinkBase + "?" +
          "deviceLinkType=" + deviceLinkType +
          "&sessionToken=" + sessionToken +
          "&sessionType=" + sessionType +
          "&version=" + version +
          "&lang=" + lang;

        Console.WriteLine(unprotectedDeviceLink);
    }
}
const deviceLinkBase = "https://smart-id.com";
const deviceLinkType = "App2App";
const sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
const sessionType = "auth";
const version = "1.0";
const lang = "eng";

const unprotectedDeviceLink = deviceLinkBase + '?' +
  'deviceLinkType=' + deviceLinkType +
  '&sessionToken=' + sessionToken +
  '&sessionType=' + sessionType +
  '&version=' + version +
  '&lang=' + lang;

console.log(unprotectedDeviceLink);
device_link_base = "https://smart-id.com"
device_link_type = "App2App" # One of "Web2App", "App2App", "QR"
session_token = "wGIrqveE6AuGDATZKmR1mtAZ"
session_type = "auth"
version = "1.0"
lang = "eng"

unprotected_device_link = device_link_base + "?" +
  "deviceLinkType=" + device_link_type +
  "&sessionToken=" + session_token +
  "&sessionType=" + session_type +
  "&version=" + version +
  "&lang=" + lang

puts unprotected_device_link
Example 23. unprotectedDeviceLink parameter (App2App authentication)
https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng
Example 24. unprotectedDeviceLink parameter (App2App signature)
https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=sign&version=1.0&lang=eng
Example 25. unprotectedDeviceLink parameter (App2App certificate-choice)
https://smart-id.com/device-link?deviceLinkType=App2App&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=cert&version=1.0&lang=eng

The final device link URL without the authCode field. RP must use deviceLinkType = Web2App for flows that start from a browser, deviceLinkType = App2App for flows that start from an RP app, and deviceLinkType = QR for cross-device flows.

elapsedSeconds value must not be added for Web2App and App2App flows.

unprotectedDeviceLink must be assembled as follows to be used in authCodePayload calculation:

unprotectedDeviceLink := STR-CONCAT(
        deviceLinkBase, "?",
        "deviceLinkType=", deviceLinkType,
        "&elapsedSeconds=", TO-STRING(elapsedSeconds),
        "&sessionToken=", sessionToken,
        "&sessionType=", sessionType,
        "&version=", version,
        "&lang=", lang)
  • Java

  • PHP

  • Python

  • Go

  • Rust

  • Kotlin

  • C#

  • Node.js

  • Ruby

public class UnprotectedDeviceLink {

  public static void main(String[] args) {

    String deviceLinkBase = "https://smart-id.com";
    String deviceLinkType = "QR";
    int elapsedSeconds = 22;
    String sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
    String sessionType = "auth";
    String version = "1.0";
    String lang = "eng";

    String unprotectedDeviceLink = deviceLinkBase + "?" +
      "deviceLinkType=" + deviceLinkType +
      "&elapsedSeconds=" + elapsedSeconds +
      "&sessionToken=" + sessionToken +
      "&sessionType=" + sessionType +
      "&version=" + version +
      "&lang=" + lang;

    System.out.println(unprotectedDeviceLink);
  }
}
<?php

$deviceLinkBase = "https://smart-id.com";
$deviceLinkType = "QR";
$elapsedSeconds = 22;
$sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
$sessionType = "auth";
$version = "1.0";
$lang = "eng";

$unprotectedDeviceLink = $deviceLinkBase . "?" .
'deviceLinkType=' . $deviceLinkType .
'&elapsedSeconds=' . $elapsedSeconds .
'&sessionToken=' . $sessionToken .
'&sessionType=' . $sessionType .
'&version=' . $version .
'&lang=' . $lang;

echo $unprotectedDeviceLink . PHP_EOL;

?>
device_link_base = "https://smart-id.com"
device_link_type = "QR"
elapsed_seconds = 22
session_token = "wGIrqveE6AuGDATZKmR1mtAZ"
session_type = "auth"
version = "1.0"
lang = "eng"
unprotected_device_link = device_link_base + "?" + \
  "deviceLinkType=" + device_link_type + \
  "&elapsedSeconds=" + str(elapsed_seconds) + \
  "&sessionToken=" + session_token + \
  "&sessionType=" + session_type + \
  "&version=" + version + \
  "&lang=" + lang

print(unprotected_device_link)
package main

import (
	"fmt"
	"strconv"
)

func main() {
	var deviceLinkBase string = "https://smart-id.com"
	var deviceLinkType string = "QR"
	var elapsedSeconds int = 22
	var sessionToken string = "wGIrqveE6AuGDATZKmR1mtAZ"
	var sessionType string = "auth"
	var version string = "1.0"
	var lang string = "eng"

	var unprotectedDeviceLink string = deviceLinkBase + "?" +
		"deviceLinkType=" + deviceLinkType +
		"&elapsedSeconds=" + strconv.Itoa(elapsedSeconds) +
		"&sessionToken=" + sessionToken +
		"&sessionType=" + sessionType +
		"&version=" + version +
		"&lang=" + lang

	fmt.Printf("%q\n", unprotectedDeviceLink)
}
fn main() {
    let device_link_base: &str = "https://smart-id.com";
    let device_link_type: &str = "QR";
    let elapsed_seconds: i32 = 22;
    let session_token: &str = "wGIrqveE6AuGDATZKmR1mtAZ";
    let session_type: &str = "auth";
    let version: &str = "1.0";
    let lang: &str = "eng";

    let unprotected_device_link: String = format!("{}?deviceLinkType={}&elapsedSeconds={}&sessionToken={}&sessionType={}&version={}&lang={}", device_link_base, device_link_type, elapsed_seconds, session_token, session_type, version, lang);

    println!("{}", unprotected_device_link);
}
package main

fun main() {
    val deviceLinkBase: String = "https://smart-id.com"
    val deviceLinkType: String = "QR"
    val elapsedSeconds: Int = 22
    val sessionToken: String = "wGIrqveE6AuGDATZKmR1mtAZ"
    val sessionType: String = "auth"
    val version: String = "1.0"
    val lang: String = "eng"

    val unprotectedDeviceLink: String = "$deviceLinkBase" + "?" +
      "deviceLinkType=$deviceLinkType" +
      "&elapsedSeconds=$elapsedSeconds" +
      "&sessionToken=$sessionToken" +
      "&sessionType=$sessionType" +
      "&version=$version" +
      "&lang=$lang"

    println(unprotectedDeviceLink)
}
using System;

public class UnprotectedDeviceLink
{
    public static void Main(string[] args)
    {
        string deviceLinkBase = "https://smart-id.com";
        string deviceLinkType = "QR";
        int elapsedSeconds = 22;
        string sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
        string sessionType = "auth";
        string version = "1.0";
        string lang = "eng";

        string unprotectedDeviceLink = deviceLinkBase + "?" +
          "deviceLinkType=" + deviceLinkType +
          "&elapsedSeconds=" + elapsedSeconds.ToString() +
          "&sessionToken=" + sessionToken +
          "&sessionType=" + sessionType +
          "&version=" + version +
          "&lang=" + lang;

        Console.WriteLine(unprotectedDeviceLink);
    }
}
const deviceLinkBase = "https://smart-id.com";
const deviceLinkType = "QR";
const elapsedSeconds = 22;
const sessionToken = "wGIrqveE6AuGDATZKmR1mtAZ";
const sessionType = "auth";
const version = "1.0";
const lang = "eng";

const unprotectedDeviceLink = deviceLinkBase + '?' +
  'deviceLinkType=' + deviceLinkType +
  '&elapsedSeconds=' + elapsedSeconds +
  '&sessionToken=' + sessionToken +
  '&sessionType=' + sessionType +
  '&version=' + version +
  '&lang=' + lang;

console.log(unprotectedDeviceLink);
device_link_base = "https://smart-id.com"
device_link_type = "QR"
elapsed_seconds = 22
session_token = "wGIrqveE6AuGDATZKmR1mtAZ"
session_type = "auth"
version = "1.0"
lang = "eng"

unprotected_device_link = device_link_base + "?" +
  "deviceLinkType=" + device_link_type +
  "&elapsedSeconds=" + elapsed_seconds.to_s +
  "&sessionToken=" + session_token +
  "&sessionType=" + session_type +
  "&version=" + version +
  "&lang=" + lang

puts unprotected_device_link
Example 26. unprotectedDeviceLink parameter (QR authentication)
https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=auth&version=1.0&lang=eng
Example 27. unprotectedDeviceLink parameter (QR signature)
https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=sign&version=1.0&lang=eng
Example 28. unprotectedDeviceLink parameter (QR certificate-choice)
https://smart-id.com/device-link?deviceLinkType=QR&elapsedSeconds=22&sessionToken=wGIrqveE6AuGDATZKmR1mtAZ&sessionType=cert&version=1.0&lang=eng

authCode validation form

The following web form can be used to validate authCode values.

AuthCode Calculator

AuthCode Calculator & Comparator

Session Type