Message Level Encryption (MLE)
Any third party connecting to the MFS Cards APIs need to encrypt the payload by using a shared secret key which is provided at the onboarding stage.
Shared Key Cryptography
The shared key is generated and managed on the MFS Cards platform. The steps for implementing this cryptography are:
- The sender and MFS Cards platform must both have the same key, which must be kept secret all the time
- The sender uses the shared secret key to encrypt a message(JSON body), and sends the cipher encrypted body to MFS Cards
- On receipt, the MFS Cards uses the identical key to decrypt the JSON body then does the processing. Then using same key the response JSON body is encrypted and sent to sender
- Sender then decrypts the response JSON body to get the clear response
Example - Ping Service
The Ping service body is as follows:
{
"pingID": 100
}
Using a shared encryption key, the clear body is encrypted to get the below encrypted message:
{
"encryptedBody": "eyJhbGciOiJBMjU2R0NNS1ciLCJlbmMiOiJBMjU2R0NNIiwiaXYiOiJiX3hEejEzNE5WN29fTHBOIiwidGFnIjoiM2Y3TVdrNHNRdmJRaHlrUTRTc05rUSJ9.WZnaZh9LgXQE6ESmSegBv9AJC-w7YUOApw1dKwj14HQ.4_vygU9XW9-vc6Fs.NyEY9Cw6lzaKQYK6wg0NmsA.eHuaLmWBJFQRdkhmxp14cQ"
}
Using above, the Ping is called and below encrypted response is received:
{
"encryptedBody": "eyJhbGciOiJBMjU2R0NNS1ciLCJlbmMiOiJBMjU2R0NNIiwiaXYiOiJsSl85WGE3bHdrTXRKczQ4IiwidGFnIjoiQnFhQjFMeEtlSHlCU29tc05MbHAxdyJ9.VmplQkXwPaROpRqI5sBoo1YpDy7WMTj6sI6pzCdRJYg.Satj1sTyMpNCibRF.5SkjefPIM34-mFb0Bdmlq4XeOIH6dRWvW7LGj6Qh_cQHKav_qKn1SCP2nulybjltljyUTfO5IN2PfOT1GOzK0dYJ342pjHTKLxc5HXk.-NjOv5KjP7YrtF4y27dn1A"
}
Then using same shared key, the sender decrypted the response to get the clear body:
{
"pongId": 101,
"errorCode": "0000",
"errorMessage": "SUCCESS"
}
Sample Code - Java
package com.utils;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.spec.SecretKeySpec;
import org.jose4j.jwe.ContentEncryptionAlgorithmIdentifiers;
import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers;
import org.jose4j.lang.JoseException;
public static String encrypt(String sharedSecret, String text)throws NoSuchAlgorithmException, UnsupportedEncodingException, JoseException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(sharedSecret.getBytes("UTF-8"));
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A256GCMKW);
jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_256_GCM);
jwe.setKey(new SecretKeySpec(digest, "AES"));
// content you want to encrypt
jwe.setPayload(text);
String serializedJwe = jwe.getCompactSerialization();
return serializedJwe;
}
public static String decrypt(String sharedSecret, String text) throws NoSuchAlgorithmException, UnsupportedEncodingException, JoseException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(sharedSecret.getBytes("UTF-8"));
JsonWebEncryption receiverJwe = new JsonWebEncryption();
receiverJwe.setCompactSerialization(text);
receiverJwe.setKey(new SecretKeySpec(digest, "AES"));
String plaintext = receiverJwe.getPlaintextString();
return plaintext;
}
Updated over 1 year ago