淘寶開(kāi)放平臺(tái)開(kāi)發(fā)文檔
/ 電子憑證發(fā)碼sign驗(yàn)證
電子憑證發(fā)碼sign驗(yàn)證
背景:
基于安全考慮,電子憑證要求碼商回調(diào)接口的時(shí)候,需要一個(gè)驗(yàn)證。為了碼商能夠快速對(duì)接,所以向碼商文檔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; /** * 碼商驗(yàn)證簽名樣例 * 本樣例中包含參數(shù)encode過(guò)程及decode過(guò)程,具體代碼請(qǐng)酌情參考,使用MD5散列算法 */ public class EticketSignTest { /** * constants */ public static final String SERCERT = "2cfa34be957db3e005761555a1c21020"; //電子憑證下發(fā)的驗(yàn)證秘鑰 public static final String CHARSET = "GBK"; //使用的字符集 public static final String param = "valid_ends=2015-04-30 23:59:59, outer_iid=23, item_title=八大處游樂(lè)玩套票, taobao_sid=244122, order_id=92555987, sku_properties=出發(fā)月份:3月;出發(fā)日期:任意1天;門(mén)票類(lèi)別:優(yōu)惠票;酒店房型:公寓, 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=驗(yàn)證碼$code.您已成功訂購(gòu)銀科環(huán)企提供的八大處游樂(lè)玩套票,有效期2015/03/23至2015/04/30,消費(fèi)時(shí)請(qǐng)出示本短信以驗(yàn)證.如有疑問(wèn),請(qǐng)聯(lián)系賣(mài)家., num_iid=442320, seller_nick=測(cè)試專(zhuān)用, mobile=185747533, sub_outer_iid=23"; /** * 電子憑證decode過(guò)程,data為各項(xiàng)參數(shù) * @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(); // 把所有參數(shù)名和參數(shù)值串在一起 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); // 把二進(jìn)制轉(zhuǎn)化為大寫(xiě)的十六進(jìn)制 return byte2hex(bytes); } public String merchantDecode(String paramFromTaobao) throws IOException { //這里的param是服務(wù)器接收到的參數(shù),具體獲取方式請(qǐng)自行斟酌,這里只寫(xiě)出decode過(guò)程 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; } /** * 將二進(jìn)制轉(zhuǎn)換成16進(jìn)制大寫(xiě) * @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
- 關(guān)于此文檔暫時(shí)還沒(méi)有FAQ