1、安全規範java
1:把當前時間戳加入請求GET參數,字段名爲_timeandroid
2:把公鑰加入請求GET參數,字段名爲_ak
3:把全部須要傳遞的參數的key按字母順序進行排序(升序),空的參數不參與校驗
4:排序所參數拼接成請求的字符串,如_ak=abcde&_time=2343243&key1=%E5%8F%82%E6%95%B02&key2=%E5%8F%82%E6%95%B01
5:把第三步所的字符串與_sk連接在一塊兒做md5,生成的字符串加到_sign參數裏,一併傳到服務器api
注意:
1: 全部字符采用utf8編碼
2: 參數必須先進行urlencode,再md5安全
3:只對GET內的參數作簽名,簽名參數附在url後面傳遞服務器
package com.android.deskclock.utils; import android.text.TextUtils; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; /** * Tool to get signed request of letv server. * */ public class LeSignature { private static final String KEY_TIME ="_time"; private static final String KEY_AK = "_ak"; private static final String PARAMS_SEP = "&"; private static final String REQUEST_CHARSET = "UTF-8"; private static final char HEX_DIGITS[] = "0123456789abcdef".toCharArray(); private static String toHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 2); for (byte b : bytes) { sb.append(HEX_DIGITS[(b & 0xf0) >>> 4]); sb.append(HEX_DIGITS[b & 0x0f]); } return sb.toString(); } private static String join(Iterable<String> strings, String sep) { StringBuilder sb = new StringBuilder(); boolean first = true; for (String item : strings) { if (first) { first = false; } else { sb.append(sep); } sb.append(item); } return sb.toString(); } /** * Get sign string of request params. * <p> * See <code>http://wiki.letv.cn/pages/viewpage.action?pageId=37325204</code> * * @param accessKey Access key of client. * @param secretKey Secret key of client. * @param params Params of request. * @param time Current timestamp. * @return Result of sign */ public static String getSignature(String accessKey, String secretKey, Map<String, String> params, long time) { if (isEmpty(accessKey) || isEmpty(secretKey)) { throw new IllegalArgumentException("You MUST set access key and secret key for the request!"); } SortedSet<String> set = new TreeSet<String>(); try { set.add(KEY_TIME + "=" + URLEncoder.encode(String.valueOf(time), REQUEST_CHARSET)); set.add(KEY_AK + "=" + URLEncoder.encode(accessKey, REQUEST_CHARSET)); if (params != null && params.size() > 0) { for (String param : params.keySet()) { String value = params.get(param); if (!TextUtils.isEmpty(value)) { set.add(param + "=" + URLEncoder.encode(value, REQUEST_CHARSET)); } } } String paramsString = join(set, PARAMS_SEP); String str2Sign = paramsString + secretKey; MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(str2Sign.getBytes(REQUEST_CHARSET)); return toHexString(digest.digest()); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } /** * Get sign string of request params and body. * <p> * See <code>http://wiki.letv.cn/pages/viewpage.action?pageId=37323874</code> * * @param accessKey Access key of client. * @param method Method of request, liking POST, GET etc. * @param path Path of request, for example "/api/v1/message". * @param body Body of request. * @param time Current timestamp. * @param params Params of request. * @return Result of sign */ public static String getSignature(String accessKey, String method, String path, byte[] body, long time, Map<String, String> params) { if (isEmpty(accessKey)) { throw new IllegalArgumentException("You MUST set access key for request!"); } try { String bodyMD5 = ""; if (body != null && body.length != 0) { MessageDigest digest; digest = MessageDigest.getInstance("MD5"); digest.update(body); bodyMD5 = toHexString(digest.digest()); } String paramString = ""; if (params != null && params.size() > 0) { SortedSet<String> set = new TreeSet<String>(); for (String param : params.keySet()) { String value = params.get(param); if (!TextUtils.isEmpty(value)) { set.add(param + "=" + value); } } paramString = join(set, PARAMS_SEP); } SimpleDateFormat fm=new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss z"); String date = fm.format(new Date(time)); String stringToSign = method.toUpperCase() + "\n" + path + "\n" + bodyMD5 + "\n" + date + "\n" + paramString; SecretKeySpec signingKey = new SecretKeySpec(accessKey.getBytes(), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(signingKey); byte[] rawHmac = mac.doFinal(stringToSign.getBytes()); return toHexString(rawHmac); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } return ""; } private static boolean isEmpty(CharSequence str) { return (str == null || str.toString().trim().length() == 0); } }