API invocation method
...
Signature algorithm
Signature demonstration
Java language demo
1min
Java
import cn.hutool.core.util.HexUtil;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.TimeZone;
public class SignatureDemo {
private final static String PARTNER_CODE = "AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******";
private final static String PARTNER_TOKEN = "Gu5t9xGARNpq86cd98joQYCN3*******";
private final static Charset UTF8 = StandardCharsets.UTF_8;
private final static String SECRET_ID = PARTNER_CODE;
private final static String SECRET_KEY = PARTNER_TOKEN;
// prod
// private final static String HOST = "api.klavi.ai";
// dev
private final static String HOST = "api-testing.klavi.ai";
public static void main(String[] args) throws Exception {
// buildCreateConsentSignature();
// buildGetInstitutionListSignature();
buildSubmitCredentialsSignature();
// buildCheckStatusSignature();
// buildSubmitMFAInfoSignature();
// buildUpdateProductsSignature();
// buildDeleteAccountSignature();
}
private static void buildCreateConsentSignature() throws Exception {
String httpRequestMethod = "POST";
String canonicalUri = "/link/external/v3/createConsent";
String canonicalQueryString = "";
String canonicalHeaders = "content-type:application/json;charset=UTF-8\n" + "host:" + HOST + "\n";
String signedHeaders = "content-type;host";
String payload = "{\"email\":\"jyNRPSqqXaGuhBWlgh1ErMoiaiEPSODaja3Jiz1GWUPKhD8zSMXub/MeRZRkLHe" +
"/2VLqHaGBilY6Da02lJb8ibdTFGK1d0LN63FeE5/0f5Ysih3D5eMNL13I4XMHMwZ+ZK0lJSiWUxLq+5tDVcgoZScuv4pa" +
"/WPXlcZI9VD+410=\",\"phone\":\"e6m4qEIaqVDA7o33e8NrBahBjpzdUZYSnLYjDcoeKq56lrxPR9Snkyn50r" +
"+L7jQ3mY6AiTE/z0gornvxxRBjeiQqOpYNUlHrq2H6XM2cDSexsziO6ZKL2PVawM2Sbf5sezVuRYACEdytUvry" +
"/AhsegyNUPMPbWTYMdOUx2ffq3c=\"," +
"\"isKi\":\"kvG6zBoklC8LCpnJ25HtcPc7acYuLk0yUWMS0I8mgLAinP5BJIWAKFqLDwQcJP7UZMYE7Gb8ufz9Rbu3gzygiI" +
"+KzyirEpOwUDNYpYdkH+rbXbsQlNKSiriIizBL6FtQYg/LUeYtAFBAUXWQh1M33cTNYcK9DfclDaj7ye5Pzkw=\"}";
String timestamp = getTimestamp();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
buildSignature(httpRequestMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders,
payload, date, timestamp);
}
private static void buildGetInstitutionListSignature() throws Exception {
String httpRequestMethod = "GET";
String canonicalUri = "/link/external/v3/getInstitutionList";
String canonicalQueryString = "";
String canonicalHeaders = "content-type:application/x-www-form-urlencoded\n" + "host:" + HOST + "\n";
String signedHeaders = "content-type;host";
String payload = "";
String timestamp = getTimestamp();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
buildSignature(httpRequestMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders,
payload, date, timestamp);
}
private static void buildSubmitCredentialsSignature() throws Exception {
String httpRequestMethod = "POST";
String canonicalUri = "/link/external/v3/submitCredentials";
String canonicalQueryString = "";
String canonicalHeaders = "content-type:application/json;charset=UTF-8\n" + "host:" + HOST + "\n";
String signedHeaders = "content-type;host";
String payload = "{\"consentId\":\"202cb962ac59075b964b07152d234b70\"," +
"\"email\":\"aw/6B0KMZRVbBIdUp0uB/pZz97ZJfJgO4LaBRm7bBvRTo25HNwW0GkcELlFuMuw0krXDQO9gLqat49LA" +
"/tgofERQrOJe0saTJt0bgue3FLSgjPP06HLdCHMgY2ApwUlIO/1otGuNYMa+m7zeT7+Cs3zEscPfwU3bC4pz39zLwNM=\"," +
"\"agency\":\"DvZXoz6wMQHfys81ak4GHK+A2/F3ClQ7rV2JxXEGDDBjenQG3rb/MvX" +
"+PKTLaUCiL92ym2bEkfEzvkzJTvdQuZV1dXwyVjbsSByFA" +
"+JbOcRdn0LtyFxcJzYLmPUwnwAVarWhKiwguE2cNbKqpdxmxkGVAN6g2ghnC4zNPpXFsYA=\"," +
"\"account\":\"evltwIAmaE12SPDKwKspH9D9PDA9HbAXq1xkaMShZflWPCIwODyXZx6alFAz7U443ZZX0wfuMc" +
"+IHcFBKYvjDFoVds0NfQjVfBvx2lcj/WXx9ZQpUjkUsOfbZnfUg2SW79Y5Y7PEaPFxsKgYXb1yZNRQwvmLLrbRZyDDxNnDnIA" +
"=\",\"password\":\"XfGzloZbejN+S/4+be31aJr8HWdImYuMUZkn1nudYHwVvzvM4se6CH89gekXOUFvn1w" +
"/VFWHu1JHBEIoiP57Qc3eJ1YbnddKl0Px1QqwVVW/+9shxbPmNoM36WY6Uebn/kxB0iGlsyhNytyBwVPyjow298" +
"/UMuNw0PRe7esZKSo=\",\"institutionCode\":\"237\"," +
"\"accountLevel\":\"VmWC5cxnerhoiEAD4sYNEmjEmG87XYymV6f1MSULPY8ETnRN" +
"+SQM3eUAKUshL6k05JGtkkKfou52RsCYa7Mtec8ZurRdx6k6C1+dRNyZmsrVl9OtQBtvwxgtdlENgzRaombKH" +
"/18kxnDPEBXCBf3FV7dtRaXL7j6CXFq3O86a4g=\"}";
String timestamp = getTimestamp();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
buildSignature(httpRequestMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders,
payload, date, timestamp);
}
private static void buildCheckStatusSignature() throws Exception {
String httpRequestMethod = "GET";
String canonicalUri = "/link/external/v3/checkStatus";
String canonicalQueryString = "traceId=kJuktDQkvHezWtYyiPYOKwxr2ddByeb8";
String canonicalHeaders = "content-type:application/x-www-form-urlencoded\n" + "host:" + HOST + "\n";
String signedHeaders = "content-type;host";
String payload = "";
String timestamp = getTimestamp();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
buildSignature(httpRequestMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders,
payload, date, timestamp);
}
private static void buildSubmitMFAInfoSignature() throws Exception {
String httpRequestMethod = "POST";
String canonicalUri = "/link/external/v3/submitMFAInfo";
String canonicalQueryString = "";
String canonicalHeaders = "content-type:application/json;charset=UTF-8\n" + "host:" + HOST + "\n";
String signedHeaders = "content-type;host";
String payload = "{\"traceId\":\"kJuktDQkvHezWtYyiPYOKwxr2ddByeb8\"," +
"\"code\":\"mb6kW19VXYU9ZvRb3TzUJ0jeei2ACETOZkt67J5zBTIbDW" +
"+7Y3qnq7WI3gHckFCsebGxArhobZ78ZhTVOZpApiJ9fBUXA7AX3b9LK8daCHtAodQquT6TcW0Flt2v305ELB4HGNwLFR3EO9L" +
"/vX5UU1VjSe3+pGGJFl7y554nwmM=\"}";
System.out.println(payload);
String timestamp = getTimestamp();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
buildSignature(httpRequestMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders,
payload, date, timestamp);
}
private static void buildUpdateProductsSignature() throws Exception {
String httpRequestMethod = "POST";
String canonicalUri = "/link/external/v3/updateProducts";
String canonicalQueryString = "";
String canonicalHeaders = "content-type:application/json;charset=UTF-8\n" + "host:" + HOST + "\n";
String signedHeaders = "content-type;host";
String payload = "{\"connectionKey\":\"1033b652e0c84acab018a9482cae3176\"}";
String timestamp = getTimestamp();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
buildSignature(httpRequestMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders,
payload, date, timestamp);
}
private static void buildDeleteAccountSignature() throws Exception {
String httpRequestMethod = "POST";
String canonicalUri = "/link/external/v3/deleteAccount";
String canonicalQueryString = "";
String canonicalHeaders = "content-type:application/json;charset=UTF-8\n" + "host:" + HOST + "\n";
String signedHeaders = "content-type;host";
String payload = "{\"connectionKey\":\"1033b652e0c84acab018a9482cae3176\"}";
String timestamp = getTimestamp();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
buildSignature(httpRequestMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders,
payload, date, timestamp);
}
private static void buildSignature(String httpRequestMethod, String canonicalUri, String canonicalQueryString,
String canonicalHeaders,
String signedHeaders, String payload, String date, String timestamp) throws Exception {
String algorithm = "K1-HMAC-SHA256";
String service = "cbms";
// step 1: build canonical request string
System.out.println(payload);
String hashedRequestPayload = sha256Hex(payload);
String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
System.out.println("**********canonicalRequest**********");
System.out.println(canonicalRequest);
// step 2: build string to sign
String credentialScope = date + "/" + service + "/" + "k1_request";
String hashedCanonicalRequest = sha256Hex(canonicalRequest);
String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
System.out.println("\n\n**********stringToSign**********");
System.out.println(stringToSign);
// step 3: sign string
byte[] secretDate = hmac256(("K1" + SECRET_KEY).getBytes(UTF8), date);
System.out.println("secretDate:" + HexUtil.encodeHexStr(secretDate));
byte[] secretService = hmac256(secretDate, service);
System.out.println("secretService:" + HexUtil.encodeHexStr(secretService));
byte[] secretSigning = hmac256(secretService, "k1_request");
System.out.println("secretSigning:" + HexUtil.encodeHexStr(secretSigning));
String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
System.out.println("\n\n************signature:" + signature);
// step 4: build authorization
String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", "
+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
System.out.println("************authorization:" + authorization);
}
private static byte[] hmac256(byte[] key, String msg) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
mac.init(secretKeySpec);
return mac.doFinal(msg.getBytes(UTF8));
}
private static String sha256Hex(String s) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] d = md.digest(s.getBytes(UTF8));
return DatatypeConverter.printHexBinary(d).toLowerCase();
}
private static String getTimestamp() {
return String.valueOf(System.currentTimeMillis() / 1000);
}
}
Updated 06 Dec 2023
Did this page help you?