文档中心 > 发票管家

发票管家进阶功能

更新时间:2017/01/12 访问次数:391

支付后申请开票跳转商户系统链接验签说明

  1. 开票链接由商户系统提供给发票管家
  2. 发票管家跳转商户系统开票时携带参数列表进行加签,采用ECC算法加签(验签源码及调用示例代码下文详细给出,请开发者关注)

ECC验签代码示例

验签调用示例

public static void main(String[] args){
       String publicKey=#替换发票管家分配的publickey#;
       String sign=#替换sign#;
       String token;
       try {
           token= URLEncoder.encode("#替换token#", "UTF-8");
        } catch (Exception e) {
            // TODO: handle exception
        }
 
       Map<String, String> params=new HashMap<String, String>();
       params.put("einv_trade_id",#替换einv_trade_id#");
       params.put("m_short_name", #替换m_short_name#);
       params.put("random", #替换random#);
       params.put("sub_m_short_name", #替换sub_m_short_name#);
       params.put("timestamp", #替换timestamp#);
       params.put("token", token);
       System.out.println(ECCUtil.verify(publicKey, params, sign));
   }

验签工具代码

package com.alipay.common.util;

import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * ECC验签工具
 * @author 
 * @version $Id: ECCUtil.java, v 0.1 2016年7月28日 下午7:56:49  Exp $
 */
public class ECCUtil {

    /** 算法 */
    public static String        algorithm  = "SHA256withECDSA";

    /** 提供者  */
    public static String        provider   = "BC";

    static {
        Security.addProvider(new BouncyCastleProvider());
    }



    /**
     * 验签
     * @param publicKey 公钥
     * @param context 加签内容
     * @param sign 签名
     * @return 验签是否通过
     * @throws Exception 异常
     */
    public static boolean verify(PublicKey publicKey, String context, String sign) throws Exception {

        /** ECDSA签名 */
        Signature ecdsaSign = Signature.getInstance(algorithm, provider);

        ecdsaSign.initVerify(publicKey);

        ecdsaSign.update(context.getBytes());

        return ecdsaSign.verify(Base64.decodeBase64(sign.getBytes()));
    }

    /**
     * 验签
     * @param publicKey 公钥字符串
     * @param params 参数
     * @param sign 签名
     * @return 是否验签通过
     */
    public static boolean verify(String publicKey, Map<String, String> params, String sign) {

        try {
            PublicKey pubKey = initPublicKey(publicKey);

            String context = getSignatureContent(params);

            return verify(pubKey, context, sign);

        } catch (Exception e) {
            LoggerUtil.error(e, logger, "验签异常,[publicKey={0};params={1};sign={2}]", publicKey,
                params, sign);
            return false;
        }
    }

    /**
     * 获得需要签名的数据,按照参数名字母升序的顺序将所有参数用&连接起来。
     * 
     * @param params 待签名参数集
     * @return 排好序的待签名字符串
     */
    public static String getSignatureContent(Map<String, String> params) {
        if (params == null) {
            return null;
        }
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            content.append((i == 0 ? "" : "&") + key + "=" + value);
        }

        return content.toString();
    }

    /**
     * 初始化公钥
     * @param pubKey 公钥字符串
     * @return 公钥
     * @throws Exception 异常
     */
    public static PublicKey initPublicKey(String pubKey) throws Exception {
        PublicKey publicKey = null;
        X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(pubKey
            .getBytes()));

        KeyFactory keyFactory = KeyFactory.getInstance("ECDSA");
        // 取公钥匙对象
        publicKey = keyFactory.generatePublic(bobPubKeySpec);

        return publicKey;
    }
   
}

FAQ

关于此文档暂时还没有FAQ
返回
顶部