Product Introduction
Authentication
Authentication

# 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 raw string.
  • Use api_secret to sign raw with the HMAC-SHA1 algorithm.
  • Splice the generated signature and raw together, then apply Base64 encoding to finally produce a sign.

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_secret must be used together with the matching api_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;
}