訪問服務器安全規範

 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);
    }
}
相關文章
相關標籤/搜索