MD5加密

Message-Digest:字节串的Hash变换,将一个任意长度的字节串变幻成一定长(128位)的大整数。

  • 这种变换只与字节的值有关,与字符集或编码方式无关。
  • 是不可逆的,无法将一个MD5的值变换回原始的字符串。
  • 高度离散型,原信息的一点小变化MD5就会有很大变化

1. API接口签名验证方法

1> 将所有请求参数按字母顺序排列得到Map,然后将key和value拼接得到参数字符串
2> 将参数字符串进行MD5加密(大写),得到签名Sign


  • 请求的唯一性
    在请求参数中,加入时间戳timestamp

/// <param name="parameters">所有字符型的请求参数</param>
/// <param name="secret">签名密钥</param>
/// <param name="qhs">是否前后都加密进行签名</param>
        public string SignRequest(IDictionary<string, string> parameters, string secret, bool qhs)
        {
            // 第一步:把字典按Key的字母顺序排序
            IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
            IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
            // 第二步:把所有参数名和参数值串在一起
            StringBuilder query = new StringBuilder(secret);
            while (dem.MoveNext())
            {
                string key = dem.Current.Key;
                string value = dem.Current.Value;
                if (!string.IsNullOrWhiteSpace(key))//!string.IsNullOrWhiteSpace(value) 空值也加入计算??
                {
                    query.Append(key).Append(value);
                }
            }
            if (qhs)
            {
                query.Append(secret);
            }
            // 第三部:使用md5运算
            MD5 md5 = MD5.Create();
            byte[] bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));
            // 第四部:把二进制转为大写的十六进制
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                result.Append(bytes[i].ToString("X2"));
            }
            return result.ToString();
        }

        /// <summary>
        /// 验证签名
        /// </summary>
        /// <returns></returns>
        public bool ValidateSign(string secret)
        {
            string method = HttpContext.Current.Request.HttpMethod;
            System.Collections.Specialized.NameValueCollection form = HttpContext.Current.Request.QueryString;
            switch (method)
            {
                case "POST":
                    form = HttpContext.Current.Request.Form;
                    break;
                case "GET":
                    form = HttpContext.Current.Request.QueryString;
                    break;
                default:
                    return false;
            }
            IDictionary<string, string> parameters = new Dictionary<string, string>();
            string sign = string.Empty;
            for (int i = 0; i < form.Count; i++)
            {
                string key = form.Keys[i];
                if (string.Equals(key,"sign",StringComparison.OrdinalIgnoreCase))
                {
                     sign = form["sign"];
                    continue;
                }
                parameters.Add(key,form[key]);
            }
            return string.Equals(SignRequest(parameters, secret, false), sign,StringComparison.OrdinalIgnoreCase);
        }

2. MessageDigest类

  • 1> 初始化实例
      Java.security.MessageDigest类是一种提供密码安全消息摘要如SHA-1和MD5功能的引擎类。
      对于特定类型的消息摘要算法而言,可通过调MessageDigest类中的getInstance静态方法得到MessageDigest对象(算法名大小写不敏感):
  Public static MessageDigest getInstance(String algorithm)

例如:

   MessageDigest.getInstance(“SHA-1”);

  调用者可以可选的制定提供者名,也可以指定provider实例,但必须保证请求算法的实现来自于指定的提供者:

  public static MessageDigest getInstance(String algorithm,String provider)
  public static MessageDigest getInstance(String algorithm,Provider provider)

  对getInstance方法的调用,会返回一个已初始化的MessageDigest对象,因此不需要进一步初始化对象。

  • 2> 提供数据
    public void update(byte input)
    public void update(byte[] input)
    public void update(byte[] input,int offset,int len)
  • 3>计算摘要
    public byte[] digest()
    public byte[] digest(byte[] input)
    // 返回摘要存储在buf中,offset位置,len字节数
    public int digest(byte[] buf,int offset,int len)

package michael.utils;
import java.security.MessageDigest;

public class EncoderHandler {

    private static final String ALGORITHM = "MD5";

    private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    /**
     * encode By MD5
     *
     * @param str
     * @return String
     */
    public static String encodeByMD5(String str) {
        if (str == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(ALGORITHM);
            messageDigest.update(str.getBytes());
            return getFormattedText(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * Takes the raw bytes from the digest and formats them correct.
     *
     * @param bytes
     *            the raw bytes from the digest.
     * @return the formatted bytes.
     */
    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j = 0; j < len; j++) {     
            buf.append(HEX_DIGITS[(bytes[j] > 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }

    public static void main(String[] args) {
        System.out.println("111111 MD5  :"
                + EncoderHandler.encodeByMD5("111111"));
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值