最近接的新项目 加密比较多 我就记录下。
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; }
哎 历时两天 我终于看完了 大致也知道了每个方法是做什么的。这是我第一次自己尝试阅读源码。之前都是看大佬的博客。
加油!!!!希望不对的 大家指出来 我们一起进步呀!!!
浙公网安备 33010602011771号