淘宝开放平台开发文档
/ 电子凭证发码sign验证
电子凭证发码sign验证
背景:
基于安全考虑,电子凭证要求码商回调接口的时候,需要一个验证。为了码商能够快速对接,所以向码商文档demo。
demo:
import java.io.IOException; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * 码商验证签名样例 * 本样例中包含参数encode过程及decode过程,具体代码请酌情参考,使用MD5散列算法 */ public class EticketSignTest { /** * constants */ public static final String SERCERT = "2cfa34be957db3e005761555a1c21020"; //电子凭证下发的验证秘钥 public static final String CHARSET = "GBK"; //使用的字符集 public static final String param = "valid_ends=2015-04-30 23:59:59, outer_iid=23, item_title=八大处游乐玩套票, taobao_sid=244122, order_id=92555987, sku_properties=出发月份:3月;出发日期:任意1天;门票类别:优惠票;酒店房型:公寓, timestamp=2015-03-24 14:39:46, send_type=2, consume_type=0, num=1, valid_start=2015-03-23 00:00:00, token=e05a6fc4082c518e2a222e145b10aebf, sub_method=1, method=send, sms_template=验证码$code.您已成功订购银科环企提供的八大处游乐玩套票,有效期2015/03/23至2015/04/30,消费时请出示本短信以验证.如有疑问,请联系卖家., num_iid=442320, seller_nick=测试专用, mobile=185747533, sub_outer_iid=23"; /** * 电子凭证decode过程,data为各项参数 * @param data * @return * @throws IOException */ public String eticketEncode(String paramToMerchant) throws IOException { String[] paramList = paramToMerchant.split(", "); Map<String, String> sortedParams = new TreeMap<String, String>(); for (int i=0;i<paramList.length;i++) { String[] paramKeyValue = paramList[i].split("="); if (paramKeyValue.length == 2) { sortedParams.put(paramKeyValue[0],paramKeyValue[1]); } } Set<Map.Entry<String, String>> paramSet = sortedParams.entrySet(); // 把所有参数名和参数值串在一起 StringBuilder query = new StringBuilder(SERCERT); for (Map.Entry<String, String> param : paramSet) { if (isNotEmpty(param.getKey()) && isNotEmpty(param.getValue())) { query.append(param.getKey()).append(param.getValue()); } } // 使用MD5加密 byte[] bytes =MD5(query.toString(), CHARSET); // 把二进制转化为大写的十六进制 return byte2hex(bytes); } public String merchantDecode(String paramFromTaobao) throws IOException { //这里的param是服务器接收到的参数,具体获取方式请自行斟酌,这里只写出decode过程 String[] paramList = paramFromTaobao.split(", "); // 把字典按Key的字母顺序排序 Map<String,String> sortedParams = new TreeMap<String, String>(); for (int i=1;i<paramList.length;i++) { String[] paramKeyValue = paramList[i].split("="); if (paramKeyValue.length == 2) { sortedParams.put(paramKeyValue[0],paramKeyValue[1]); } } Set<Map.Entry<String, String>> paramSet = sortedParams.entrySet(); StringBuilder query = new StringBuilder(); query.append(SERCERT); for (Map.Entry<String, String> param : paramSet) { if (isNotEmpty(param.getKey()) && isNotEmpty(param.getValue())) { query.append(param.getKey()).append(param.getValue()); } } System.out.println(query); byte[] bytes =MD5(query.toString(), CHARSET); return byte2hex(bytes); } /** * 将字符串encode成MD5值 * @param data * @param charset * @return * @throws IOException */ public static byte[] MD5(String data, String charset) throws IOException { byte[] bytes = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); bytes = md.digest(data.getBytes(charset)); } catch (GeneralSecurityException gse) { throw new IOException(gse.getMessage()); } return bytes; } /** * 将二进制转换成16进制大写 * @param bytes * @return */ public static String byte2hex(byte[] bytes) { StringBuilder sign = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(bytes[i] & 0xFF); if (hex.length() == 1) { sign.append("0"); } sign.append(hex.toUpperCase()); } return sign.toString(); } public static boolean isNotEmpty(String str) { return ((str != null) && (str.length() > 0)); } public static void main(String[] args) throws IOException { EticketSignTest sample = new EticketSignTest(); String eticket = sample.eticketEncode(param); String merhcnat = sample.merchantDecode(param); if (eticket.equals(merhcnat) ) { System.out.println(eticket); // System.out.print("yes"); System.out.println(merhcnat); } } }
FAQ
- 关于此文档暂时还没有FAQ