Certificates

Complying to PSD2 and RTS security requirements and in accordance with Berlin Group XS2A Framework, Piraeus Bank supports the identification of TPPs via qualified certificates at both the transport (QWAC) and application layer (QSEAL):

  • The use of QWACs is mandatory and provides the necessary identification data that TPPs have to present to Piraeus Bank for secure data exchange. As described below, in the current version of PSD2 APIs, TPPs must include the content of their QWAC’s PEM in a specific header (X-Client-Certificate), regardless of how they have set up their TLS-connection.
  • The use of QSEALs is optional and allows certificate suppliers (TPPs) to guarantee that the submitted data is indeed generated by them. If TPPs decide to sign their request messages at the application layer using QSEAL certificates, then they have to follow the specific guidelines provided by Piraeus Bank and described below.

Therefore, Piraeus Bank supports two alternative security schemes:

  1. Use of QWAC (mandatory)
  2. Use of QWAC (mandatory) and QSEAL (optional)

 

Use of QWACs

Communication between Piraeus Bank and TPPs is always secured via a TLS-connection using TLS version 1.2 or higher. This TLS-connection is mutually authenticated, so the TPP  needs to provide a qualified certificate for authentication (QWAC). This QWAC has to be issued by a qualified trust service provider according to eIDAS regulation, while the content of the certificate must be compliant to the requirements set by PSD2 and RTS, based on which the certificate of the TPP must indicate all authorized roles (AISP, PISP, CBPII).

Consequently, the TPPs must use their QWAC certificate when establishing their TLS-connection.

However, in the current version of Piraeus Bank’s PSD2 APIs, TPPs should also include the content of their QWAC PEM file in a particular request header (X-Client-Certificate), after having removed the prefix line “-----BEGIN CERTIFICATE-----”, the postfix line “-----END CERTIFICATE-----” and any newline characters.

Example

X-Client-Certificate: MIIGEzCPu….MeTnWxq== 

 

Use of QSEALs

TPPs who want to ensure that the transmitted data are not tampered with, must use QSEAL certificates to sign their request.  In order to do that the following headers must be included in the request:

1.  Digest: Contains a Base64 encoded Hash of the message body. The only accepted hash algorithms that can be used to calculate the Digest are SHA-256 and SHA-512.

The steps to calculate the digest are:

  1. Minify the body, or take an empty string if there is no body.  To minify the body, serialize it, with no formatting.
  2. Calculate the SHA-256 or SHA-512 Hash of the body.
  3. Encode it to Base64 format.
  4. Fill the following pattern with the encoded string:  HashingAlgorithm=Base64EncodedHashOfRequestBody

Example

    • Body to sign

{
    "payload" : "some string"
}

    • Minified body

{“payload”:”some string”}

    • SHA-256 hash of the minified body

0928f3cfb7e7bce828ca86a3f7d8cc771786a5ba99343930f0f05717f54b8d12

    • Base64 encoding of the body hash

MDkyOGYzY2ZiN2U3YmNlODI4Y2E4NmEzZjdkOGNjNzcxNzg2YTViYTk5MzQzOTMwZjBmMDU3MTdmNTRiOGQxMg==

    • Digest:

SHA-256=MDkyOGYzY2ZiN2U3YmNlODI4Y2E4NmEzZjdkOGNjNzcxNzg2YTViYTk5MzQzOTMwZjBmMDU3MTdmNTRiOGQxMg==

 

2.  TPP-Signature-Certificate: The PEM-formatted certificate of the QSeal used for signing the request, after having removed the prefix line “-----BEGIN CERTIFICATE-----”, the postfix line “-----END CERTIFICATE-----” and any newline characters, leaving the Base64 part.

Example

TPP-Signature-Certificate: MIITCzCEu….MfLnQxq== 

 

3.  Signature: The “Signature” header consists of the following components:

      • keyId: Serial Number of the TPP's certificate.  This should match the serial number in the “TPP-Signature-Certificate” header of this request.  This number can be found executing the following “openssl x509 -in qseal-cert.pem -noout -text”.  The serial number can be found under “Serial Number”, eg: 6a:a3:…..19:03.  Pass the value removing colon punctuation marks.  In windows 10, openssl can be found in “c:\program files\git\usr\bin\”
      • algorithm: The name of the algorithm used to generate the digital signature. Must be either “rsa-sha256” or “rsa-sha512”.
      • headers: List of HTTP headers included when generating the signature for the message. Must be equal to "digest x-request-id" for the time being, for all requests.
      • signature: The signing string, signed with the private QSeal key, and the result is Base64 encoded.  signature parameter (lower case s) is part of the Signature header (Upper case S).  Signing string contains the information noted in headers parameter.

The steps to produce Signature are:

  1. Prepare the Digest as described in step 1.
  2. Prepare signing string

    a)   Add each header name (noted in “headers” parameter) with its value separated by live breaks.  The order of the headers should be the same as noted in “headers” parameter.
    b)   Base64 encode it

  3. Sign the Base64 encoded signing string, with the algorithm noted in “algorithm” field, using the private key of the QSeal (the private key’s id is in the keyId parameter).  Be sure to use Pkcs1 padding.
  4. Base64 encode the output of the above signed data
  5. Put all the variables (keyId, algorithm, headers, signature) with their values, comma separated in the Signature header      


Example 1: RSA-256

    • Body to sign

{
   "payload" : "some string"
}

    • Minified body

{“payload”:”some string”}

    • SHA-256 hash of the minified body

0928f3cfb7e7bce828ca86a3f7d8cc771786a5ba99343930f0f05717f54b8d12

    • Base64 encoding of the body hash

MDkyOGYzY2ZiN2U3YmNlODI4Y2E4NmEzZjdkOGNjNzcxNzg2YTViYTk5MzQzOTMwZjBmMDU3MTdmNTRiOGQxMg==

    • Digest

SHA-256=MDkyOGYzY2ZiN2U3YmNlODI4Y2E4NmEzZjdkOGNjNzcxNzg2YTViYTk5MzQzOTMwZjBmMDU3MTdmNTRiOGQxMg==

    • Signing string

digest: SHA-256=MDkyOGYzY2ZiN2U3YmNlODI4Y2E4NmEzZjdkOGNjNzcxNzg2YTViYTk5MzQzOTMwZjBmMDU3MTdmNTRiOGQxMg==\nx-request-id: 1f58df29-d312-4a1a-a006-4068ae994071

   (Note: use only \n to separate the two variables, and not \r or \r\n)

    • Base64 encoding of the Singing string

ZGlnZXN0OiBTSEEtMjU2PU1Ea3lPR1l6WTJaaU4yVTNZbU5sT0RJNFkyRTRObUV6Wmpka09HTmpOemN4TnpnMllUVmlZVGs1TXpRek9UTXdaakJtTURVM01UZG1OVFJpT0dReE1nPT0KeC1yZXF1ZXN0LWlkOiAxZjU4ZGYyOS1kMzEyLTRhMWEtYTAwNi00MDY4YWU5OTQwNzE=

    • Signed data (depends on clients private key)

Byte array can’t be directly displayed.  Don’t convert it to string before encoding it to Base64.  Encode the data directly.

    • Base64 encoding of the Signed data

FMVSTGgdfeafti06NFZNsHAIwVoiaLx7wYXxxfXJiVpyAG3wykS14KK4xS2kSOMtF38ZUB2Ee4JVH9gZti/euae3/QQKNL0NklaGWA8KfjxEJFijvDuBjWX34t1PWYQ329+8jZPdgc78WFGBg69OssNNhvhhJYR6i+GKszvsUxD2lJgQfF+OqfLrUU2DyVEIjfMIgCpQ2AI1fmJLqeEl4jlW2cTlUdnffghGlsAMidec34KGz5woyxMWVYAQbHp0egKDiQFcd6jQQqcaJWA/VtdVm1fqKPuSSbEqnfeC6S8cA0fYUsRTKes57/QJ2KUx8/PX4Qbs01VUDbdSg2cEkg==

    • Signature

keyId=” 6AA32860FF20999C9D12A78ADBDB1903”, algorithm=”rsa-sha256”, headers=”digest x-request-id”, signature=” FMVSTGgdfeafti06NFZNsHAIwVoiaLx7wYXxxfXJiVpyAG3wykS14KK4xS2kSOMtF38ZUB2Ee4JVH9gZti/euae3/QQKNL0NklaGWA8KfjxEJFijvDuBjWX34t1PWYQ329+8jZPdgc78WFGBg69OssNNhvhhJYR6i+GKszvsUxD2lJgQfF+OqfLrUU2DyVEIjfMIgCpQ2AI1fmJLqeEl4jlW2cTlUdnffghGlsAMidec34KGz5woyxMWVYAQbHp0egKDiQFcd6jQQqcaJWA/VtdVm1fqKPuSSbEqnfeC6S8cA0fYUsRTKes57/QJ2KUx8/PX4Qbs01VUDbdSg2cEkg==”

 

Example 2: RSA-512

    • Body to sign

{
    "payload" : "some string"
}

    • Minified body

{“payload”:”some string”}

    • SHA-256 hash of the minified body

4985112e5260722a435b8cb04d462f7c012576d42dd85f55af6c49d69901192d85f1154cd0698240557781845252020d19b6fa0200a6e25cef0702fce7edf10a

    • Base64 encoding of the body hash

NDk4NTExMmU1MjYwNzIyYTQzNWI4Y2IwNGQ0NjJmN2MwMTI1NzZkNDJkZDg1ZjU1YWY2YzQ5ZDY5OTAxMTkyZDg1ZjExNTRjZDA2OTgyNDA1NTc3ODE4NDUyNTIwMjBkMTliNmZhMDIwMGE2ZTI1Y2VmMDcwMmZjZTdlZGYxMGE=

    • Digest

SHA-512=NDk4NTExMmU1MjYwNzIyYTQzNWI4Y2IwNGQ0NjJmN2MwMTI1NzZkNDJkZDg1ZjU1YWY2YzQ5ZDY5OTAxMTkyZDg1ZjExNTRjZDA2OTgyNDA1NTc3ODE4NDUyNTIwMjBkMTliNmZhMDIwMGE2ZTI1Y2VmMDcwMmZjZTdlZGYxMGE=

    • Signing string

digest: SHA-512=NDk4NTExMmU1MjYwNzIyYTQzNWI4Y2IwNGQ0NjJmN2MwMTI1NzZkNDJkZDg1ZjU1YWY2YzQ5ZDY5OTAxMTkyZDg1ZjExNTRjZDA2OTgyNDA1NTc3ODE4NDUyNTIwMjBkMTliNmZhMDIwMGE2ZTI1Y2VmMDcwMmZjZTdlZGYxMGE=\nx-request-id: 49caf623-0b89-4f22-bcd0-d8cd444303b2

    • Base64 encoding of the Sining string

ZGlnZXN0OiBTSEEtMjU2PU1Ea3lPR1l6WTJaaU4yVTNZbU5sT0RJNFkyRTRObUV6Wmpka09HTmpOemN4TnpnMllUVmlZVGs1TXpRek9UTXdaakJtTURVM01UZG1OVFJpT0dReE1nPT0KeC1yZXF1ZXN0LWlkOiAxZjU4ZGYyOS1kMzEyLTRhMWEtYTAwNi00MDY4YWU5OTQwNzE=

    • Signed data (depends on clients private key)

Byte array can’t be directly displayed.  Don’t convert it to string before encoding it to Base64.  Encode the data directly.

    • Base64 encoding of the Signed data

ZGlnZXN0OiBTSEEtNTEyPU5EazROVEV4TW1VMU1qWXdOekl5WVRRek5XSTRZMkl3TkdRME5qSm1OMk13TVRJMU56WmtOREprWkRnMVpqVTFZV1kyWXpRNVpEWTVPVEF4TVRreVpEZzFaakV4TlRSalpEQTJPVGd5TkRBMU5UYzNPREU0TkRVeU5USXdNakJrTVRsaU5tWmhNREl3TUdFMlpUSTFZMlZtTURjd01tWmpaVGRsWkdZeE1HRT0KeC1yZXF1ZXN0LWlkOiA0OWNhZjYyMy0wYjg5LTRmMjItYmNkMC1kOGNkNDQ0MzAzYjI=

    • Signature

keyId=” 6AA32860FF20999C9D12A78ADBDB1903”, algorithm=”rsa-sha512”, headers=”digest x-request-id”, signature=” HUZMuEt1j3P7CvrUKKsUygCBzU69ZKwITcdbSMEL1cli1iusY57nKZYoEjfg49h0m3lCOW3Rmjl68iic494bFDg6hzvjm0RvroU17O0zNikkJf1XGDUqupNAo4lpB3F7Bg/0p4m8M8PK0V6XMvrwq2UlcjNBvWJ34M+DmRVWS3a8n6y7erNBa4JjOe1QNGmAQLl3VhOZytjRXQVFdR4K+zZyAWAJUTMHDs7pA7UYPdDIzCzZTQ4NpjWNuZSRZ+qqH9lVuTObg4Bb/FPSmmG2nEUvttVNRwEeT9UVf4bF2sSKKqxUj9TOjOUrmKOVqWseu//QxOGmYQQf2YI0n5kLWw==”