arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 5

T1Authentication (EN)

Loading...

Loading...

Loading...

Loading...

Loading...

Trust1Connector installation in Trust1Authentication

These pages describe the installation of the Trust1Connector during the first usage of Trust1Authentication

After the verification of the mobile number, the Trust1Authenticator will verify if the Trust1Connector is installed on the end-users device. If this is the case and the end-user has a card reader with his eID installed, the eID will be read and used for the authentication.

If the Trust1Authentication detects that the Trust1Connector is not installed the user will be requested to download the Trust1Connector and install it. Trust1Authentication will detect he operating system of the end-users device and present to him the most appropriate links. If the end-user would like to use a different version of the Trust1Connector he can click on "all download links".

The Trust1Connector will be downloaded. You can retrieve the package in your donwload folder.

Install the package

After installation of the Trust1Connector Trust1Authentication will continue the user flow if an eID is available.

The end-user will be asked to give his consent

After giving consent the authentication flow will continue as described in the User manual.

Overview

A brief introduction for the Trust1Authentication Service

hashtag
Introduction

The T1Authentication service, hosted by Trust1Team is an authentication page which can be used to authenticate users to your application using:

  • smart cards, tokens or other hardware identity means

  • Smart-ID mobile app

The service is web layer on top of the to enable smart token interactions with a local device. The concept enforced by using the Trust1Connector, is to enable a decentralized Identity borker which in solely control of the end-user, the user of your web application.

Benefits when using the Trust1Authentication service:

  • very quick and easy integration (see further and try it out)

  • dynamic configurable means (ways for a user to autenticate)

  • detailed report for certificate validation

hashtag
User Interaction Flow

The Relying Party can opt-in for multiple authentication means. An authentication mean is for example:

  • 'beid': use Belgian eID smart card for authentication

  • 'smart-id: use SmartID mobile application for user authentication

Depending on the allowed authentication means, the user is redirected to the authentication page. The authentication flow is summarized in the image below:

The steps for a user Authentication are:

  • Verify phone

  • Verify secret (OTP)

  • [Optional] Select Authentication mean

  • Identify

After a succesfull user authentication, the user is redirected back to the Relying Party application. When the Relying Party has provided a webhook initially, a HTTP POST request will be provided to the application, prior to the user redirect.

The POST request, contains the following information:

  • result status

  • session context (RP application parameters, correlation ID)

  • session tracker information (process step results, tracing information)

no need to dive into detailed security implementation in a complex domain
  • dynamic branding with customizable authentication flows

  • low-cost and maintained externally

  • Authentication

    validation report (JSON formatted report of the certificate validation)
    Trust1Connectorarrow-up-right
    User Interaction Flow

    Integration

    Trust1Authentication - Authenticate users using a decentralized Identity Broker (Trust1Connector)

    hashtag
    Endpoints

    Acceptance/Staging: https://acc-auth.t1t.euarrow-up-right

    Production: https://auth.t1t.euarrow-up-right

    hashtag
    Integration Steps

    The integration can be summarized in 2 required steps, and 1 optional step:

    • start a new session and redirect the user to the authentication page

    • parse the result (through a webhook) and give access to requester (user of your application)

    • [optionally] retrieve a detailed validation report

    hashtag
    Postman Collection

    The HTTP REST collection is available on

    hashtag
    Overview Sequence Flow

    The following sequence diagram denotes partially the steps executed, with regards to the user who needs to be authenticated.

    hashtag
    Start a new Session

    The initial call sets the context for a new session. The context must be unique for each user who needs to log in. Once the context has been created a JWT is issued and can be used to redirect the user to the authentication page.

    hashtag
    Set Context

    A new session can be started by initiating a POST request with your provided 'apikey':

    hashtag
    Properties

    property
    value type
    description

    circle-info

    The pubKey used must be a

    4096 bit RSA

    , the encryption padding uses is:

    PKCS1_OAEP

    circle-exclamation

    hashtag
    The webhooUri and redirectUri, when not provided, no feedback is provided to the consumer, the consumer needs to GET the information using the HTTP/REST API.

    hashtag
    Example Response

    The HTTP reponse contains a Json reponse with a token property

    The token MUST be set for the end-user to start the flow on the Authentication web page.

    The token is added as a query parameter on the URL for the Authentication web page:

    From here the user will be guided through the authentication flow

    hashtag
    Optional: Provide a public key for response encryption

    In the set context request, an optional public key can be provided by the web application who wants to use the Trust1Authentication service.

    When a public key is provided, the biometric information from the authentication user will be encrypted with the provided public key, on the user's device itself, avoiding any data to be leaked during the authentication flow.

    No sensitive data is stored on the Trust1Authentication service.

    hashtag
    Parse the received result (success)

    Once the user has completed the flow, the webhookUri will be used, prior to initiating the redirect (redirectUri).

    The webhook MUST be a POST HTTP endpoint, who will expect the following data to be received:

    The included bio data is provided as a Json string (encrypted only if the session has been created with a public key property).

    The Json has the following format:

    When there is no bio information available (typically for PKCS11 only tokens), the bio not be provided upon a successful authentication response

    hashtag
    Parse the received result (failed)

    When the session has been expirect, and no successfull result has been pushed OR when the use case fails in a way that the end-user is blocked, a response will be sent to the webhook with isSuccess: false An additional error property is added with more explanation. The session context and tracker is always provided in the respone:

    hashtag
    Parse the received result (cancelled)

    When a user cancels, the webhook is called with a similar response as the failure response. The main difference is that the cancel_state property will be set to false

    hashtag
    Examples

    hashtag
    Generate 4096 bit RSA Keypair

    The RSA keypair generated MUST have a size of 4096 bit:

    Public key must be send in a base64 encoded format!

    Copy base64 encoded public key as a single string to the clipboard (Mac example):

    Setting up the session context, becomes

    The following response contains a token, which can be used to redirect the user to the login page:

    Redirect URL:

    Architecture

    hashtag
    High-level architecture

    The following component diagram denotes the interfaces and services involved:

    Trust1Authentication Components Overview

    User manual

    This document describes the user interface and the steps that a user needs to go through to get authenticated. It is assumed that the Trust1Connector is installed.

    From the customers webpage the user is redirected to the authentication pages of Trust1Team. These pages can be branded according to the colour scheme and logo of the customer.

    hashtag
    Landing page for first authentication

    circle-info

    At any time in the authentication flow the user can return to the previous page by pressing the arrow next to the titel of the authentication step (on the left side of the screen)

    The user is first requested to link his mobile to his account so that in a later stage he can quickly authenticate using his mobile phone and a OTP (One Time Password)

    In the top right corner that language can be changed. Default is English, but also Dutch, French and German are offered. Other languages can be added on customer request.

    Below the logo, the authentication steps are indicated. Once a step is completed the next step will light up so that the user knows where he is in the process.

    After entering a valid phone number the customer will receive a OTP on this mobile.

    The OTP is a 4-digit numerical code. The user needs to enter this number in the appropriate field. The user has a limited time ( configurable parameter) in which the OTP is valid. If the user did not receive an OTP he can request to receive a new one. (Resend OTP token)

    If the end-user enters a correct OTP, he will be redirected to the identification page (third step).

    The user can choose between different identification means: Card reader or Smart-ID

    hashtag
    Card reader

    If the end-user does not have a card reader connected to his device or his ID eID inserted in the card reader The Identity selection page will remain blanc. There will not be any available readers.

    If the end-user has not got the Trust1Connector installed he will be asked to do so (.)

    The blue banner on the screen is an example on how "recent" discovered issue with an OS is tackled until a new version of the T1C is released or until the OS is updated.

    By clicking on the available identity the certificates of the eID are read.

    When the certificates are valid, the user will be receive a green confirmation that the certificates are qualified and gets a button "Authentication" that will lead him to the next step where he needs to enter his pincode.

    If the certificates are not valid, the token is expired or the user is trying to use the token twice, the user will get a red warning of invalid certificates.

    After pressing the authenticate button the user receive a pop-up window in which he needs to enter the pin-code of his eID.

    After entering a valid pin-code the user will be redirected to the customers portal. The user can also cancel the authentication by pressing the cancel button.

    The user will only have 3 attempts to enter the correct pin-code. If the users enters 3 consecutive times the wrong pin-code his ID card will be blocked.

    hashtag
    Smart-ID

    The user can also chose to use Smart-ID as an authentication method.

    After selecting Smart-ID the user can either enter his National Registration Number or scan the QR-code that is displayed.

    hashtag
    Using National Registration Number

    The user needs to enter his National Registration Number and click continue. In the next screen the users needs to click on authenticate to continue

    The user will than receive a code on the screen and a notification on his mobile phone to verify the code. The user will have to enter his authentication pin-code (pin-code 1) in the Smart-ID app to be authenticated.

    hashtag
    Using QR-code

    If the user scans the QR-code with this Smart-ID app he will be asked to enter his authentication pin-code and is than immediatly authenticated. Please note that for security reasons the QR-code changes every second. This does not impact the functionality.

    installation manual

    webhookUri

    Option[string]

    this is the URI which will be used by the service to POST a HTTP (Json) request with the authentication flow result

    sessionTimeInMinutes

    integer

    this defines the expiration time of the issues JWT token, and hence the time in which the session will stay valid

    pubKey

    Optional[string]

    base64 encoded PEM for the public key provided by the integration provider (consuming web application); the key is used to encrypt sensitive data (biometric property in the webhook response) received from the authenticating user

    lang

    Optional[string]

    nl, fr, en, de (the languaged loaded by default)

    correlationId

    string

    A UNIQUE identifier created by the service consumer

    useCase

    string

    predefined use case: "auth" starts the authentication flow

    means

    list of strings

    denotes which means should be available for the end-user; when 'beid' and 'luxid' are added, user device will search for Belgian eID and Luxembourg ID tokens in connected readers. The abbreviations allign with the Trust1Connector module names. All registered tokens from the Trust1Connector can be uses

    redirectUri

    Option[string]

    Postmanarrow-up-right
    Simplified authentication sequence flow

    This is the page where the user is redirected towards, once the flow has been completed (for both success AND failure scenario)

    // Example redirect URL
    https://auth.t1t.eu?token={{received JWT from SET context}}
    curl --location 'http://localhost:9000/v1/token' \
    --header 'apikey: {{secret_api_key}}' \
    --header 'Content-Type: application/json' \
    --data '{
        "correlationId": "06c74b0b-f5f5-4b71-847d-5813bde62e63",
        "useCase": "auth",
        "means": ["beid", "luxid","smart-id"],
        "redirectUri": "https://trust1team.com",
        "webhookUri": "https://mbwgm22d.ngrok.app",
        "sessionTimeInMinutes": 30
    }'
    {
        "token": "eyJ0eXAiOiJKV1Qi...wtZpmCWoJVQ"
    }
    // Example redirect URL
    https://auth.t1t.eu?token=eyJ0eXAiOiJKV1Qi...wtZpmCWoJVQ
    {
        "sessionContext": {
            "id": "66961584-a00d-46dc-96e6-c494582e99f2",
            "org_id": "187144be-e4ef-4826-8845-93057ac4fae3",
            "org_name": "Trust1Team",
            "correlation_id": "06c74b0b-f5f5-4b71-847d-5813bde62e63",
            "use_case": "auth",
            "means": "beid,luxid",
            "redirect_uri": "https://trust1team.com",
            "webhook_uri": "https://mbwgm22d.ngrok.app",
            "webhook_http_method": "POST",
            "session_time_in_minutes": 30,
            "created_at": "2024-05-02T07:10:44.490751"
        },
        "sessionTracker": {
            "id": "66961584-a00d-46dc-96e6-c494582e99f2",
            "token_issued": true,
            "token_validated": true,
            "connector_installed": true,
            "reader_connected": true,
            "identity_found": true,
            "mean_pin_result": true,
            "mean_cert_valid": true,
            "gsm_input": true,
            "gsm_otp_input": true,
            "gsm_otp_code": "1938",
            "gsm_nr": "+32...",
            "auth_digest_signed": "ZmVkZGJlMmM5NWNiYzA1YmI2N2ZlOGI4YTg2ZGE0Mzk5NzAxZTkwN2Y3NmFhMjQyOGE3Mjg1ZTM0YzZlNjljNg==",
            "error_state": false,
            "cancel_state": false,
            "success_state": true,
            "result_state": "SEND",
            "created_at": "2024-05-02T07:10:44.500004",
            "updated_at": "2024-05-02T09:12:10.315752"
        },
        "bio": "bio OR encrypted(bio)",
        "validationReport": "https://acc-auth-api.t1t.eu/v1/auth/report/06c74b0b-f5f5-4b71-847d-5813bde62e63",
        "isSuccess": true
    }
    {
            "birthDate": "03 MEI 2001",
            "birthLocation": "Leuven",
            "cardDeliveryMunicipality": "Brussel",
            "cardNumber": "000001244125",
            "cardValidityDateBegin": "05.07.2022",
            "cardValidityDateEnd": "05.07.2032",
            "chipNumber": "U0xHkAJRAAAiJSiPEpIDYw==",
            "documentType": "1",
            "firstNames": "Nora Angèle",
            "name": "Specimen",
            "nationalNumber": "01050399963",
            "nationality": "BELG",
            "nobleCondition": "",
            "pictureHash": "R2osQHL1+wdkLiVtXt/XnGpnX8aSYtMn+ZeQUVF7CAE=",
            "rawData": "AQwwMDAwMDEyNDQxMjUCEFNMR5ACUQAAIiUojxKSA2MDCjA1LjA3LjIwMjIECjA1LjA3LjIwMzIFB0JydXNzZWwGCzAxMDUwMzk5OTYzBwhTcGVjaW1lbggMTm9yYSBBbmfDqGxlCQAKBEJFTEcLBkxldXZlbgwLMDMgTUVJIDIwMDENAVYOAA8BMRABMBEgR2osQHL1+wdkLiVtXt/XnGpnX8aSYtMn+ZeQUVF7CAE=",
            "sex": "V",
            "signature": "MGYCMQDRA/MOgdMSE3GoJFTanZOILLdEH14T/O489tLFa1g4AsI/S0q+uw5mZzuXHKE3WXwCMQDHqPdSSfrsxsnMG1SKKz02N1X64JAORW/CdYqrAWjrI08lJVa68zgezM3FdXXGt4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
            "specialStatus": "0",
            "thirdName": "",
            "version": "0"
        }
    {
        "sessionContext": {
            "id": "66961584-a00d-46dc-96e6-c494582e99f2",
            "org_id": "187144be-e4ef-4826-8845-93057ac4fae3",
            "org_name": "Trust1Team",
            "correlation_id": "06c74b0b-f5f5-4b71-847d-5813bde62e63",
            "use_case": "auth",
            "means": "beid,luxid",
            "redirect_uri": "https://trust1team.com",
            "webhook_uri": "https://mbwgm22d.ngrok.app",
            "webhook_http_method": "POST",
            "session_time_in_minutes": 30,
            "created_at": "2024-05-02T07:10:44.490751"
        },
        "sessionTracker": {
            "id": "66961584-a00d-46dc-96e6-c494582e99f2",
            "token_issued": true,
            "token_validated": true,
            "connector_installed": true,
            "reader_connected": true,
            "identity_found": true,
            "mean_pin_result": true,
            "mean_cert_valid": false,
            "gsm_input": true,
            "gsm_otp_input": true,
            "gsm_otp_code": "1938",
            "gsm_nr": "+32...",
            "auth_digest_signed": "ZmVkZGJlMmM5NWNiYzA1YmI2N2ZlOGI4YTg2ZGE0Mzk5NzAxZTkwN2Y3NmFhMjQyOGE3Mjg1ZTM0YzZlNjljNg==",
            "error_state": true,
            "cancel_state": false,
            "success_state": false,
            "result_state": "ACKED",
            "created_at": "2024-05-02T07:10:44.500004",
            "updated_at": "2024-05-02T09:12:10.315752"
        },
        "error": "[blocking] Certificate validation failed",
        "validationReport": "https://acc-auth-api.t1t.eu/v1/auth/report/06c74b0b-f5f5-4b71-847d-5813bde62e63",
        "isSuccess": false
    }
    ```shell
    # Generate rsa private key
    openssl genrsa -out key.pem 4096
    
    # Generate rsa public key
    openssl rsa -in key.pem -outform PEM -pubout -out public.pem
    ```
    ```shell
    base64 --encode < key.pem | tr -d '[[:space:]]' | pbcopy
    base64 --encode < public.pem | tr -d '[[:space:]]' | pbcopy
    ```
    LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF2UzR2bWtTaHFLaE02ZStLcGtPcQp5L2s1OXdMejBaWDJ4TkNmZG53YWFLcktBem9NZHoyK3NNQllyckdDSUl5enZHWSs3S0crYkpnVkI1QU5nYndkCnpvbGZ1YjMyendoSFBtb3hwOUpPc1MxYS8rYVpybkM1RDA0T245NU1hQzIyam1xMklrMFRjSTVGd0gzei9lalIKN2VYMXd1bVYzQTVZZERWWExJZzF3WERrOUd2MkJVSzhFd1NCNWc4SnMvMm5zcEEvekpScTEyTzUzRVUvL3dNZwp2ekt1cW9sTWJrWVlEQ1JyZTd3U0ErZlpVbnI0QkNtUE1IZXlGZG02S3diaVdhVGFId0o2VEpnR3Zra1d6Y1gyCmNFZFlkby9LYUxnaDRNaGtERkFOb1ZQZi9CV205QjRYbEFZdFV4UVpvV3BSeVEyeUVoK2N5SGljbnBhR1ZSQXMKRkdmenNZcFllVkExeDhkaERUYXphdmFRdDcwQ3R0U2FMQXVITDJaTnp2cjNkUng4dzY0WFFFVW4zdlF5eS9XMwpFQ0ljNnV1WlV1NE1iUGY0bS8yVzdCRGxtb01DTmFaZWxhR1JwbzZMYyswa1JQZGFtdHJaRURBd1NNcDNEeGNjCjN0ZzZ5dkRqdVV2T1YrYnE1N0V6NzRzQ0lNNmJyMWxjdndhNWRDaG4wNXU5Q0gySGlQbm5tSDhUcHp2ZndUQm4KNld1RnR4RmhUZEtGYVc0Q25vbkxoYmY2ZWxaWXFvQmtkbGQwYU4xSFdhbXFUN3V1dUM3Q005NlpQVkxjY1dhMApxYzNlbFNQZEZjdytVeFBubzQwd3JmbklWS3VwNUxWSlFlWEdmNWp6b0l1UU9WVHBFSnVHbGR4Q0ZSRHdBODNHCnA1MmNUblFOaXBNWVRTTWlXRzQvSUlVQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=
    curl --location 'http://localhost:9000/v1/token' \
    --header 'apikey: {{apikey}}' \
    --header 'Content-Type: application/json' \
    --data '{
        "correlationId": "06c74b0b-f5f5-4b71-847d-5813bde62e63",
        "useCase": "auth",
        "means": ["beid", "luxid", "gsm", "smartid"],
        "redirectUri": "https://trust1team.com",
        "webhookUri": "https://mbwgm22d.ngrok.app",
        "sessionTimeInMinutes": 30,
        "pubKey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF2UzR2bWtTaHFLaE02ZStLcGtPcQp5L2s1OXdMejBaWDJ4TkNmZG53YWFLcktBem9NZHoyK3NNQllyckdDSUl5enZHWSs3S0crYkpnVkI1QU5nYndkCnpvbGZ1YjMyendoSFBtb3hwOUpPc1MxYS8rYVpybkM1RDA0T245NU1hQzIyam1xMklrMFRjSTVGd0gzei9lalIKN2VYMXd1bVYzQTVZZERWWExJZzF3WERrOUd2MkJVSzhFd1NCNWc4SnMvMm5zcEEvekpScTEyTzUzRVUvL3dNZwp2ekt1cW9sTWJrWVlEQ1JyZTd3U0ErZlpVbnI0QkNtUE1IZXlGZG02S3diaVdhVGFId0o2VEpnR3Zra1d6Y1gyCmNFZFlkby9LYUxnaDRNaGtERkFOb1ZQZi9CV205QjRYbEFZdFV4UVpvV3BSeVEyeUVoK2N5SGljbnBhR1ZSQXMKRkdmenNZcFllVkExeDhkaERUYXphdmFRdDcwQ3R0U2FMQXVITDJaTnp2cjNkUng4dzY0WFFFVW4zdlF5eS9XMwpFQ0ljNnV1WlV1NE1iUGY0bS8yVzdCRGxtb01DTmFaZWxhR1JwbzZMYyswa1JQZGFtdHJaRURBd1NNcDNEeGNjCjN0ZzZ5dkRqdVV2T1YrYnE1N0V6NzRzQ0lNNmJyMWxjdndhNWRDaG4wNXU5Q0gySGlQbm5tSDhUcHp2ZndUQm4KNld1RnR4RmhUZEtGYVc0Q25vbkxoYmY2ZWxaWXFvQmtkbGQwYU4xSFdhbXFUN3V1dUM3Q005NlpQVkxjY1dhMApxYzNlbFNQZEZjdytVeFBubzQwd3JmbklWS3VwNUxWSlFlWEdmNWp6b0l1UU9WVHBFSnVHbGR4Q0ZSRHdBODNHCnA1MmNUblFOaXBNWVRTTWlXRzQvSUlVQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo="
    }'
    ```json
    {
        "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dSI6Imh0dHBzOi8vYXBpbS50MXQuYmUva2V5cy9wdWIifQ.eyJpc1NlcnZpY2VBY2NvdW50Ijp0cnVlLCJzdWIiOiI5NmNhNzI5NS0wYmU3LTQyNDQtODJlNi1mMDg4MWQ5MjU4MjMiLCJpc3MiOiJUcnVzdDFUZWFtIiwiZXhwIjoxNzE0OTczODg2LCJuYmYiOjE3MTQ5NzE0ODZ9.BuRipUci4QoeLKVVJTpybp0k2tkDvKEoznVGhcQRQGc9qOSOdaeSOcGLFJyqilaO1-EYr2PokiJcvx1oVmjV7_OY-Aq7WN_vK1Ta5Oh1Xa99BetjqQLhxi6lRbaEAw9Y-pkw_RBH3HqGEyb6TuXS7mtsm0pKz9y5nnWNcNvidniVGg28xAlu3rrDnGAIwSyCzoE3DeZj9xwQH1llF_Enx9V1F88RIm7zedNoZGGrm8tgRsmHjNDyFNhM8nMb-8395ZhMEBauFgY7HqzVHxx4AuNyviedLyNkLFltjSAqRZVViUDhJ53xermF5xEKaKe0Pilts3O-A2iHCNkgNOpHlw"
    }
    ```
    https://auth.t1t.eu/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dSI6Imh0dHBzOi8vYXBpbS50MXQuYmUva2V5cy9wdWIifQ.eyJpc1NlcnZpY2VBY2NvdW50Ijp0cnVlLCJzdWIiOiI5NmNhNzI5NS0wYmU3LTQyNDQtODJlNi1mMDg4MWQ5MjU4MjMiLCJpc3MiOiJUcnVzdDFUZWFtIiwiZXhwIjoxNzE0OTczODg2LCJuYmYiOjE3MTQ5NzE0ODZ9.BuRipUci4QoeLKVVJTpybp0k2tkDvKEoznVGhcQRQGc9qOSOdaeSOcGLFJyqilaO1-EYr2PokiJcvx1oVmjV7_OY-Aq7WN_vK1Ta5Oh1Xa99BetjqQLhxi6lRbaEAw9Y-pkw_RBH3HqGEyb6TuXS7mtsm0pKz9y5nnWNcNvidniVGg28xAlu3rrDnGAIwSyCzoE3DeZj9xwQH1llF_Enx9V1F88RIm7zedNoZGGrm8tgRsmHjNDyFNhM8nMb-8395ZhMEBauFgY7HqzVHxx4AuNyviedLyNkLFltjSAqRZVViUDhJ53xermF5xEKaKe0Pilts3O-A2iHCNkgNOpHlw