最近接的新项目 加密比较多  我就记录下。

SignUtil是jnewsdk-mer-1.0.0.jar  com.jnewsdk.util中的一个工具类。由于我没有百度到对应的信息。所以我只能看源码了。。百度不到,使我成长。

 

恩恩。。

我们先来看parseParam 

  public static Map parseParam(HttpServletRequest request)
    {
        Map map = new HashMap();
        //request.getParameterNames()方法是将发送请求页面中form表单里所有具有name属性的表单对象获取(包括button).
        // 返回一个Enumeration类型的枚举.
        Enumeration paramsEnum = request.getParameterNames();
        //boolean hasMoreElements( )
        //测试此枚举是否包含更多的元素
        while (paramsEnum.hasMoreElements())
        {
            //     Object nextElement( )
            //如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素
            String paramName = (String)paramsEnum.nextElement();
            //根据Name得到Value
            String paramValue = request.getParameter(paramName);
            map.put(paramName, paramValue);
        }
        return map;
    }

 

所以,这个方法其实就是把request请求变为key,value的格式。

public static Map parseResponse(String msg)
    {
        Map map = new HashMap();
        int beginIndex = 0;
        int endIndex = 0;
        String key;
        //for(;;) 这是一个死循环,用来等待中断
        for (;;)
        {
            //判断"="第一次出现的值
            endIndex = msg.indexOf("=", beginIndex);
            key = null;
            value = null;
            //enindex小于0  那么就是"="不存在这个msg中,就返回null的map
            //endindex等于0也是返回null的map
            if (endIndex <= beginIndex) {
                return map;
            }
            //截取0到“=”之前的值
            key = msg.substring(beginIndex, endIndex);

            //得到“=”之后一位的下标值
            beginIndex = endIndex + 1;

            if (beginIndex >= msg.length())
            {
                map.put(key, "");
                return map;
            }
            //判断"="后面是“{”吗》
            if (msg.charAt(beginIndex) == '{') {
                //得到“}”的位置+1
                endIndex = msg.indexOf("}", beginIndex) + 1;
            } else {
                endIndex = msg.indexOf("&", beginIndex);
            }
            if (endIndex < beginIndex) {
                break;
            }
            value = msg.substring(beginIndex, endIndex);
            map.put(key, value);

            beginIndex = endIndex + 1;
        }
        String value = msg.substring(beginIndex);
        map.put(key, value);

        return map;
    }

 

这个也是把响应变为Map

  /**
     * 得到url的参数
     * @param map
     * @param isSort  是否升序
     * @param removeKey 需要除掉的参数集合
     * @return
     */
    public static String getURLParam(Map map, boolean isSort, Set removeKey)
    {
        StringBuffer param = new StringBuffer();
        List msgList = new ArrayList();
        //判断Map中是否有值
        for (Iterator it = map.keySet().iterator(); it.hasNext();)
        {
            //得到Map中的键
            String key = (String)it.next();
            //得到MAP中的值
            String value = (String)map.get(key);
            //如果需要去掉的Key是null  或者不包含
            if ((removeKey == null) || (!removeKey.contains(key))) {
                //就把 key=value存入List
                msgList.add(key + "=" + StringUtils.toEmpty(value));
            }
        }
        //是否进行升序
        if (isSort) {
            Collections.sort(msgList);
        }
        for (int i = 0; i < msgList.size(); i++)
        {   //获取到List的值  并用&进行拼接
            String msg = (String)msgList.get(i);
            if (i > 0) {
                param.append("&");
            }
            param.append(msg);
            //也就是这样。。。
            //key=value&key=value
            //是不是觉得很熟悉  好像就是我们http传参就是这么做的。
        }
        return param.toString();
    }
 /**
     *  封装了之前的getURLParam方法 。
     *  区别就是这个排序一定是升序的
     * @param map
     * @param removeKey
     * @return
     */
    public static String getSignMsg(Map map, Set removeKey)
    {
        return getURLParam(map, true, removeKey);
    }
/**
     *
     * @param signMethod  加密格式  例:MD5 或者 SHA1这样子。。。
     * @param signedMsg 需要加密的信息
     * @param key
     * @param charSet 字符集 例 “UTF-8”
     * @return
     */
    public static String sign(String signMethod, String signedMsg, String key, String charSet)
    {
        try
        {   //根据字符集获取拼接字节
            byte[] data = (signedMsg + key).getBytes(charSet);
            String[] algArray = { "MD5", "SHA1", "SHA256", "SHA512" };
            String algorithm = null;
            for (int i = 0; i < algArray.length; i++) {
                //判断传进来的signMethod是否和algArray中定义的一样
                //注:equalsIgnoreCase 比较的是两个字符和长度是否一样
                //一样就返回true
                if (algArray[i].equalsIgnoreCase(signMethod))
                {
                    algorithm = algArray[i];
                    break;
                }
            }
            if (StringUtils.isEmpty(algorithm))
            {
                LogFactory.getLog().error(SignUtil.class, "签名方法错误signMethod=[" + signMethod + "]");
                return null;
            }
            //注  :这里就已经给他加密了 Base64位数
            return new String(Base64.encode(new MessageDigest(algorithm).sign(data)));
        }
        catch (Exception e)
        {
            LogFactory.getLog().error(SignUtil.class, e);
        }
        return null;
    }

接下我补一下  Base64.encode(new MessageDigest(algorithm).sign(data)

我知道 为什么叫做Base64加密  也就是基于64的加密

我在源码上看到了

private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();

 

恩 ,接下来 是

Base64.encode 这个方法。
 public static char[] encode(byte[] data)
  {
    char[] out = new char[(data.length + 2) / 3 * 4];
    int i = 0;
    for (int index = 0; i < data.length; index += 4)
    {
      boolean quad = false;
      boolean trip = false;
      int val = 0xFF & data[i];
      val <<= 8;
      if (i + 1 < data.length)
      {
        val |= 0xFF & data[(i + 1)];
        trip = true;
      }
      val <<= 8;
      if (i + 2 < data.length)
      {
        val |= 0xFF & data[(i + 2)];
        quad = true;
      }
      out[(index + 3)] = alphabet[64];
      val >>= 6;
      out[(index + 2)] = alphabet[64];
      val >>= 6;
      out[(index + 1)] = alphabet[(val & 0x3F)];
      val >>= 6;
      out[index] = alphabet[(val & 0x3F)];
      i += 3;
    }
    return out;
  }

有没有看到的大佬 帮我解释下 上面的这段代码 我对于 位运算 一直处于懵逼状态。所以我就只能贴我自己测试的结果了 。

以下是我测试的结果

package com.example.demo;

import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Vector;

public class EnumerationTest {
    private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
    public static void  main(String args[]){
       
        String name ="123456";
        byte[] b_utf8 =new byte[265];
        try {
        b_utf8 = name.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println("UTF-8=======>>"+ EnumerationTest.encode(b_utf8));   ;
        char[] test=EnumerationTest.encode(b_utf8);
        for (int i=0;i<test.length;i++){
            System.out.print(test[i]);
        }
    }
    public static char[] encode(byte[] data)
    {
        char[] out = new char[(data.length + 2) / 3 * 4];
        int i = 0;
        for (int index = 0; i < data.length; index += 4)
        {
            boolean quad = false;
            boolean trip = false;
            int val = 0xFF & data[i];
            val <<= 8;
            if (i + 1 < data.length)
            {
                val |= 0xFF & data[(i + 1)];
                trip = true;
            }
            val <<= 8;
            if (i + 2 < data.length)
            {
                val |= 0xFF & data[(i + 2)];
                quad = true;
            }
            out[(index + 3)] = alphabet[64];
            val >>= 6;
            out[(index + 2)] = alphabet[64];
            val >>= 6;
            out[(index + 1)] = alphabet[(val & 0x3F)];
            val >>= 6;
            out[index] = alphabet[(val & 0x3F)];
            i += 3;
        }
        return out;
    }
}

结果是:

 

 所以我得出结论 这是进行加密的。

 这是signUtil中最后的一个方法了 。。

 /**
     *
     *
     * @param signMethod
     * @param signedMsg
     * @param mac
     * @param key
     * @param charSet
     * @return
     */
    public static boolean verifySign(String signMethod, String signedMsg, String mac, String key, String charSet)
    {
        try
        {
            if ((StringUtils.isEmpty(mac)) || (StringUtils.isEmpty(signedMsg))) {
                return false;
            }
            return mac.equalsIgnoreCase(sign(signMethod, signedMsg, key, charSet));
        }
        catch (Exception e)
        {
            LogFactory.getLog().error(SignUtil.class, e);
        }
        return false;
    }

 

 哎 历时两天 我终于看完了  大致也知道了每个方法是做什么的。这是我第一次自己尝试阅读源码。之前都是看大佬的博客。

  加油!!!!希望不对的   大家指出来 我们一起进步呀!!!