ING API with python

2021-03-10
Python API



Table of Contents

1. ING Developer

ING has a developer portal with instructions for accessing their APIs.

There are 2 API types:

eIDAS certificates can only be optained by organizations, not by individuals like you or me

This post focus on the Open Banking API.

2. The Open Banking API

At the moment of writting of this post there is not a lot that you can do with this API. Those are the 2 APIs you can use:

As you can see right now it is not very useful. When I started investigating I didn't realized that you couldn't retrive your own data with the Open Banking API. So I followed all their documentation and developed all the code until I realized that it was not useful at all. But since I had all the code I thought it might be useful to share.

I also contacted their support and they told me they plan to allow users to access their account info with the Open Banking API. But there is no ETA for that.

3. Open Banking API Sandbox

This part follows the Getting Started with Open Banking API.

The first thing you need to do is to download the example certificates:

And also:

For requesting the token with the OAuth 2.0 API they provide a script. However I wanted to have everything in python.

The first thing is to install cryptodome with

pip install pycryptodome

All the code can be found in https://github.com/villoro/villoro_posts/tree/master/0035-ing_api

Let's break down the script in parts

3.1. Digesting and signing

You need to calculate the SHA256 of some parts. That can be done with:

from Crypto.Hash import SHA256

# to digest 'text'
digest = SHA256.new()
digest.update(text.encode())

From that we can create a function that does it and can also sign the digest with:

sign_key = "certificates/example_client_signing.key" # Adapt path

def encode_sha256(text, sign=False):
    """ digest a text with SHA256 """

    digest = SHA256.new()
    digest.update(text.encode())

    if sign:
        # Get the signing key
        with open(sign_key, "r") as file:
            data = file.read()

        private_key = RSA.importKey(data)
        signer = PKCS1_v1_5.new(private_key)
        out = signer.sign(digest)

    else:
        out = digest.digest()

    return b64encode(out).decode()

And finally we need to encode it as a base64 string with:

from base64 import b64encode

b64encode(out).decode()

3.2. Parameters

Now let's create the basic parameters:

import uuid
from datetime import datetime

mdate = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT")
digest = encode_sha256(body) # Without signing
req_id = str(uuid.uuid4())

And the headers:

headers = {
    "Date": mdate,
    "Digest": f"SHA-256={digest}",
    "X-ING-ReqID": req_id,
    "Content-Type": "application/x-www-form-urlencoded",
    "Accept": "application/json",
}

3.3. Getting the signature

In this step you need to encode with SHA256 the composition of: * endpoint * date * body digest * req_id

After that you need to append some information. All of that can be done with:

def get_signature(method, endpoint, mdate, digest, req_id):

    text = [
        f"(request-target): {method.lower()} {endpoint}",
        f"date: {mdate}",
        f"digest: SHA-256={digest}",
        f"x-ing-reqid: {req_id}",
    ]

    signature_digest = encode_sha256("\n".join(text), True)

    signature = [
        f'keyId="{client_id}"',
        'algorithm="rsa-sha256"',
        'headers="(request-target) date digest x-ing-reqid"',
        f'signature="{signature_digest}"',
    ]

    return ",".join(signature)

3.4. Doing the request

Now we need to append the authorization as a header:

signature = get_signature(method, endpoint, mdate, digest, req_id)
if token:
    headers.update({"Authorization": f"Bearer {token}", "Signature": signature})
else:
    headers.update({"Authorization": f"Signature {signature}"})

And finally we can do the request:

tls_cert="certificates/example_client_tls.cer",
tls_key="certificates/example_client_tls.key",

result = requests.request(
    method.upper(),
    self.host + endpoint,
    headers=headers,
    data=body,
    cert=(tls_cert, tls_key),
)

3.5. Getting the token

This can be done with the code explained and using those params:

4. Creating your app

In this step you need to sign in to the ing developer portal.

Then you need to create an app.

4.1. Generating your certificates

You need to generate:

You can generate the first 2 with:

# 1. Generate an RSA private key. The password of the private key can be entered during execution of the command, so it doesn't end up in the history of your shell.
openssl genrsa -out ing_http.key -passout stdin 2048
# 2. Generate the X.509 Certificate Signing Request
openssl req -sha256 -new -key ing_http.key -out ing_http.csr
# 3. Sign the X.509 certificate with your own private key
openssl x509 -req -sha256 -days 365 -in ing_http.csr -signkey ing_http.key -out ing_http.crt

Then need to repeat the 3 steps but replacing ing_http by ing_tls.

4.2. Getting a token with your API

You need to follow the same as before but changing some params:

4.3. Doing a hello world

Once you have the open you can suscribe to Showcase API. You will need to wait until your request is approved.

Once it is approved you can query the only endpoint to check that everything is working:

5. Next steps

Now you can wait with me until they add more APIs under the Open Banking.