External Authorisation Private & Public keys
Usages
Usually these keys are being used for either encrypting/decrypting or for signing/verifying.
encrypting/decrypting: This process consists in encrypting the ciphertext with a public key to ensure that no one but the entity using the private key will be authorised to decrypt the content.
signing/verifying: This process consists in creating a signature with a private key and verifying its validity with the public key. This makes ensures that the sender is who really claims to be. In addition to message Integrity and Non-repudiation.
Signing / Verifying
The signing process consists in the following steps:
Using the payload (UTF-8 Bytes) of the request that is going to be send to our client. We will hash the payload using SHA-256 and then using the private key we will generate the signature.
We will request our client’s API containing the following information:
The payload
The Signature (encoded base 64) generated from the payload (send as a header)
The keyId of the key used to generate the signature (send as a header)
The flow described can is contemplated in the image below.
The verifying process consists in the following steps:
- Receive the request
- Fetch the public key using the keyId received in the request in the client’s side.
- If It is the first time using the new key, the key won’t be found in their system. They would require to fetch the right JWK in our Authentication API (/.well-known/jwks.json), using the keyId received. Then they would store in their system for future use.
- If the key Id is found in their system they would be able retrieve the public key from their system.
- Compare the hashed payload against the decoded signature and decrypted with the public key. If the values match it means the payload is valid and it hasn’t been altered.
We can see the described steps in the following image:
Example of usage (Signing / Verifying)
We will now demonstrate the described flow in an example. Given a client that uses External balance authorisation, we need to send them transaction information so they do validations in they side and either accept or decline the transaction. This is why it is important knowing that the information send to them is not altered.
Using the private key for the specific client that we are going to request, we will sign the signature and send such signature along with the keyId for the key.
After the client receives the request containing the following information:
Request Body
Signature
KeyId
The client then, will go fetch the public key that matches the keyId given.
Now using openssl library we can verify that the payload and the signature match using the public key obtained.
Where…
publickey.pem
is the public key obtained in format PEM.signature.sha256
is the decoded base 64 value of the signature. We can decode it usingecho signatureValue | base64 -d > signature.sha256
payload.txt
is the value of the payload(without spaces or new lines) in UTF-8 Bytes. We can obtain it using echo -n "{"holdId":"c18c2ec7-16cc-400a-98b5-e3d7f1a0d152","accountId":"74eb0d63-696b-424d-9d44-56e0f73e7305","cardId":"db1c8006-96ea-4070-a53a-16d896058dc9","amount":{"amount":"-0.52","currency":"AUD"}}" | iconv -t utf-8 > payload.txt
If the payload and the signature matches the result will be “Verified OK”.
We could also verify the signature using with the following Java method:
Where…
signature
is encoded base 64.publicKeyDer64
is the value of the public key in DER base 64 value.payload.txt
is the value of the payload(without spaces or new lines). For example: "{"holdId":"c18c2ec7-16cc-400a-98b5-e3d7f1a0d152","accountId":"74eb0d63-696b-424d-9d44-56e0f73e7305","cardId":"db1c8006-96ea-4070-a53a-16d896058dc9","amount":{"amount":"-0.52","currency":"AUD"}}"