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.
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:
/greetings/single
which is the equivalent of a hello world
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.
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:
https://api.sandbox.ing.com
e77d776b-90af-4684-bebc-521e5b2614dd
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
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()
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", }
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)
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), )
This can be done with the code explained and using those params:
/oauth2/token
POST
grant_type=client_credentials
In this step you need to sign in to the ing developer portal.
Then you need to create an app.
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
.
You need to follow the same as before but changing some params:
https://api.ing.com
certificates/ing_http.key
certificates/ing_tls.crt
certificates/ing_tls.key
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:
GET
/greetings/single
Now you can wait with me until they add more APIs under the Open Banking.