API 接口加签

本文是FaTPay API 加签 的 demo

使用本文代码时,请务必将其中的合作伙伴账号相关信息替换为您自身的

package onramp.apisign;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;

/**
 * SignUtil
 *
 * @author FaTPay
 */
public class SignUtil {

    private static final Logger LOG = LoggerFactory.getLogger(SignUtil.class);

    /**
     * Signature algorithms
     */
    public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
    private static final String RSA_ALGORITHM = "RSA";

    /**
     * RSA private key
     */
    private static final String PRIVATE_KEY = "<YOUR RSA PRIVATE KEY>";

    /**
     * partnerId
     */
    private static final String PARTNERID = "<YOUR PARTNER ID>";

    /**
     * FaTPay domain
     */
    private static final String DOMAIN = "https://api.ramp.fatpay.xyz";

    /**
     * apis
     */
    private static final String ONRAMP_TOKEN = "/open/api/onramp/token";
    private static final String ONRAMP_CURRENCY = "/open/api/onramp/currency";
    private static final String ONRAMP_PRICE = "/open/api/onramp/price";
    private static final String ONRAMP_ORDER = "/open/api/onramp/order";

    /**
     * Generates the signature
     *
     * @param params
     * @param rsaPrivate
     * @return
     */
    public static String rsaSign(Map<String, String> params, String rsaPrivate, String presign) {
        try {
            rsaPrivate = StringUtils.replace(rsaPrivate, "-----BEGIN PRIVATE KEY-----", "");
            rsaPrivate = StringUtils.replace(rsaPrivate, "-----END PRIVATE KEY-----", "");
            String sign = doSign(presign + paramsToStr(params), rsaPrivate);
            return sign;
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * Generates the signature
     *
     * @param content    Content to be signed
     * @param privateKey private key
     * @return
     */
    public static String doSign(String content, String privateKey) {
        try {
            byte[] decoded = Base64.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(decoded);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
            PrivateKey priKey = keyFactory.generatePrivate(pkcs8);

            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(priKey);
            signature.update(content.getBytes(StandardCharsets.UTF_8));
            byte[] signed = signature.sign();
            return Base64.encodeBase64String(signed);
        } catch (Exception ex) {
            LOG.error("RSA sign failed,content={}", content, ex);
            throw new IllegalArgumentException("RSA sign failed");
        }
    }

    /**
     * Converts parameters into ordered strings
     *
     * @param params
     * @return
     */
    private static String paramsToStr(Map<String, String> params) {
        StringBuilder param = new StringBuilder();
        List<String> keys = new ArrayList(params.keySet());
        // Sorts the specified keys
        Collections.sort(keys);
        int index = 0;
        Iterator<String> iterator = keys.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = params.get(key);
            // Filter out null and empty values
            if ("x-fp-signature".equals(key) || "signature".equals(key) || "sign".equals(key) || StringUtils.isBlank(value)) {
                continue;
            }
            param.append(index == 0 ? "" : "&").append(key).append("=").append(value);
            index++;
        }
        return param.toString();
    }
    
    /**
     * Returns URI
     *
     * @param url
     * @return
     */
    public static URI getURI(String url) {
        if (!(StringUtils.startsWithIgnoreCase(url, "http://") || StringUtils
                .startsWithIgnoreCase(url, "https://"))) {
            url = "http://" + url;
        }
        try {
            URI uri = new URI(url);
            return uri;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // ******************** OPEN API DEMO START ********************//
    public static void openApiDemo() {
        // header
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("X-FP-Version", "v1.0");
        headerMap.put("X-FP-Timestamp", "1661338357");
        headerMap.put("X-FP-Nonce", "868964");
        headerMap.put("X-FP-Partner-Id", PARTNERID);

        // parameters
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("fiatCurrency", "USD");
        paramMap.put("currencyAmount", "199");
        paramMap.put("cryptoCurrencyCode", "USDT_ERC20");
        paramMap.put("payment", "BANK_CARD_TRANSFER");

        // Converts keys to lower case
        Map<String, String> headerMapLowerCase = new HashMap<>();
        Set<String> strings = headerMap.keySet();
        strings.forEach(s -> {
            headerMapLowerCase.put(s.toLowerCase(), headerMap.get(s));
        });

        // Parameters to be signed
        Map<String, String> params = new HashMap<>();
        params.putAll(headerMapLowerCase);
        params.putAll(paramMap);

        // example
        String url = DOMAIN.concat(ONRAMP_PRICE);
        URI uri = getURI(url);

        // prefix
        String presign = "GET" + uri.getHost() + uri.getPath() + "?";
        String sign = "";
        try {
            // Generates the signature
            sign = SignUtil.rsaSign(params, PRIVATE_KEY, presign);
        } catch (Exception e) {
            LOG.error("rsaSign error, exception:{}", e);
        }
        headerMap.put("X-FP-Signature", sign);
        // TODO Send http request with above parameters (url, paramMap, headerMap)
        LOG.info("url:{}, paramMap:{}, headerMap:{}", url, paramMap, headerMap);
    }
    // ******************** OPEN API DEMO END ********************//

}

Last updated