支付后申请开票跳转商户系统链接验签说明
- 开票链接由商户系统提供给发票管家
- 发票管家跳转商户系统开票时携带参数列表进行加签,采用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