# Authentication Instructions
# Description
Before calling an API, and in order to prevent the secret key (api_secret) from being leaked, a signature mechanism is introduced to ensure secure communication between servers. The generated signature is passed as a required parameter in subsequent API calls to guarantee information security.
# Signature Algorithm
Concatenated string: a=[api_key]&b=[expire_time]&c=[current_time]&d=[random]
Field meanings:
| Field | Corresponding item | Note |
|---|---|---|
| a | api_key | Equivalent to a username; obtained from the FinAuth console. |
| b | expire_time | The validity period of the signature. A value that conforms to the UNIX Epoch timestamp specification, in seconds. |
| c | current_time | The timestamp when the signature is generated, in seconds. When setting the signature, current_time must be smaller than expire_time. |
| d | random | An unsigned decimal integer that the user must generate, up to 10 digits. |
Note: The validity period is set so that the signature can be used multiple times within a period of time.
# Generate the signature
Use the HMAC-SHA1 algorithm to encrypt the request.
The sign generation process is as follows:
- Concatenate the individual fields to produce a
rawstring. - Use
api_secretto signrawwith the HMAC-SHA1 algorithm. - Splice the generated signature and
rawtogether, then apply Base64 encoding to finally produce asign.
The formula is as follows:
raw = "a={}&b={}&c={}&d={}".format(api_key, expire_time, current_time, random)
sign_tmp = HMAC-SHA1(api_secret, raw)
sign = Base64(''.join(sign_tmp, raw))
Note: Standard Base64 encoding is used here, not urlsafe Base64 encoding. The
api_secretmust be used together with the matchingapi_key, both of which can be obtained from the FinAuth console.
# Sample Code
# Python Code Sample
import time
import hashlib
import base64
import random
import hmac
api_key = "your api_key"
api_secret = "your api_secret"
valid_durtion = 100 # valid time is 100 seconds
current_time = int(time.time())
expire_time = current_time + valid_durtion
rdm = ''.join(random.choice("0123456789") for i in range(10))
raw = "a={}&b={}&c={}&d={}".format(api_key, expire_time, current_time, rdm)
sign_tmp = hmac.new(api_secret, raw, hashlib.sha1).digest()
sign = base64.b64encode(sign_tmp + raw)
# Java Code Sample
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Random;
public class HmacSha1Sign {
/**
* Generate the signature field
*
* @param apiKey
* @param secretKey
* @param expired
* @return
* @throws Exception
*/
public static String genSign(String apiKey, String secretKey, long expired) throws Exception {
long now = System.currentTimeMillis() / 1000;
int rdm = Math.abs(new Random().nextInt());
String plainText = String.format("a=%s&b=%d&c=%d&d=%d", apiKey, now + expired, now, rdm);
byte[] hmacDigest = HmacSha1(plainText, secretKey);
byte[] signContent = new byte[hmacDigest.length + plainText.getBytes().length];
System.arraycopy(hmacDigest, 0, signContent, 0, hmacDigest.length);
System.arraycopy(plainText.getBytes(), 0, signContent, hmacDigest.length,
plainText.getBytes().length);
return encodeToBase64(signContent).replaceAll("[\\s*\t\n\r]", "");
}
/**
* Generate Base64 encoding
*
* @param binaryData
* @return
*/
public static String encodeToBase64(byte[] binaryData) {
String encodedStr = Base64.getEncoder().encodeToString(binaryData);
return encodedStr;
}
/**
* Generate hmacsha1 signature
*
* @param binaryData
* @param key
* @return
* @throws Exception
*/
public static byte[] HmacSha1(byte[] binaryData, String key) throws Exception {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
mac.init(secretKey);
byte[] HmacSha1Digest = mac.doFinal(binaryData);
return HmacSha1Digest;
}
/**
* Generate hmacsha1 signature
*
* @param plainText
* @param key
* @return
* @throws Exception
*/
public static byte[] HmacSha1(String plainText, String key) throws Exception {
return HmacSha1(plainText.getBytes(), key);
}
}
# Objective-C Code Sample
#import "ViewController.h"
#import <CommonCrypto/CommonHMAC.h>
#import <CommonCrypto/CommonCryptor.h>
#import <math.h>
#define api_key @"your api_key"
#define api_secret @"your api_secret"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString* sign = [self getSignStr];
NSLog(@"sign = %@",sign);
}
- (NSString *)getSignStr {
int valid_durtion = 10000;
long int current_time = [[NSDate date] timeIntervalSince1970];
long int expire_time = current_time + valid_durtion;
long random = abs(arc4random() % 100000000000);
NSString* str = [NSString stringWithFormat:@"a=%@&b=%ld&c=%ld&d=%ld", api_key, expire_time, current_time, random];
NSData* sign_tmp = [self hmac_sha1:api_secret text:str];
NSData* sign_raw_data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData* data = [[NSMutableData alloc] initWithData:sign_tmp];
[data appendData:sign_raw_data];
NSString* sign = [data base64EncodedStringWithOptions:0];
return sign;
}
- (NSData *)hmac_sha1:(NSString *)key text:(NSString *)text{
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
const char *cData = [text cStringUsingEncoding:NSUTF8StringEncoding];
char cHMAC[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
return HMAC;
}
@end
# PHP Code Sample
<?php
function gen_sign($apiKey, $apiSecret, $expired){
$rdm = rand();
$current_time = time();
$expired_time = $current_time + $expired;
$srcStr = "a=%s&b=%d&c=%d&d=%d";
$srcStr = sprintf($srcStr, $apiKey, $expired_time, $current_time, $rdm);
$sign = base64_encode(hash_hmac('SHA1', $srcStr, $apiSecret, true).$srcStr);
return $sign;
}
