微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

小程序接口加密

场景

小程序请求的所有接口参数必须加密,后台返回数据也需要加密,并且增加Token验证

一、小程序功能编写

1.下载一份Js版的aesUtil.js源码。【注:文章末尾会贴出所有的相关类文件】 
2.下载一份Js版的md5.js源码。 
3.在pulic.js中进行加解密操作代码如下,其中秘钥和秘钥偏移量要与后台的一致。

  1. var CryptoJS = require('aesUtil.js'); //引用AES源码js
  2. )
  3. iv '91129048100F0494'//十六位十六进制数作为秘钥偏移量
  4. //解密方法
  5. encryptedHexStr Hex);
  6. decrypt AESdecryptsrcs, key{
  7. modemodeCBC });
  8. return decryptedStr();
  9. }
  10. Encrypt{
  11. encrypted encrypt{
  12. Pkcs7
  13. encryptedciphertext().toupperCasemoduleexportsDecrypt;
  14. 4.在网络请求帮助类中进行参数的加密和返回数据的解密操作。

    )
  15. * 网络请求
  16. requestmethod loading urlparams success fail url BASE_URL + //请求参数转为JSON字符串
  17. consolelogurl ' params=> ' jsonStr)
  18. token productionToken//加密请求参数
  19. '请求=>明文参数:')
  20. aesData)
  21. wxrequest({
  22. 'Content-Type''application/x-www-form-urlencoded;charset=utf-8' token
  23. data{
  24. //判断请求结果是否成功
  25. null //解密返回数据
  26. data);
  27. '返回=>明文数据:'result successJSON))
  28. }
  29. }

其中生成Token的规则,【生成Token的规则可根据具体的业务逻辑自己定义,我这里使用的规则是根据请求参数的字母排序取其value并加上当前时间戳再进行MD5加密】

 * 生成Token
  • obj utilobjKeySort value '';
  • }
  • value getTokenDatenewDate())
  • valuereplace/\s+/g""//进行UTF-8编码
  • md5hex_md5;
  • objKeySortobj//先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法获取属性名进行排序,newkey是一个数组
  • //创建一个新的对象,用于存放排好序的键值对  
  • //遍历newkey数组
  • newObjnewkeyi]]]];
  • //返回排好序的新对象
  • }
  • 二、服务端功能编写

    由于初学SpringMVC,使用的方式不一定是最优最好的,如有不妥善之处,请各位看官多多指教 
    思路:

    通过过滤器拦截请求参数,通过自定义参数包装器对参数进行解密。 
    拦截获取请求的Token并生成服务器端Token进行验证。 
    对返回参数通过JSON转换器进行加密处理。

    思路图 
    1.重写HttpServletRequestWrapper,在自定义的HttpServletRequestWrapper 中对参数进行处理

     * Created by 吴蜀黍 on 2018-08-07 09:37
    
  • @Slf4j
  • ParameterRequestWrapperHttpServletRequest // 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似
  • //将参数表,赋予给当前的Map以便于持有request中的参数
  • modifyParameterValues //重载一个构造方法
  • addAllParametersextendParams);//这里将扩展参数写入参数表
  • String aesParameter getParameterConstantsNetWorkAES_DATA logdebug"[modifyParameterValues]==========>加密数据:{}" aesParameter//解密
  • try decryptParameter AesUtilsaesParameterAES_KEY log"[modifyParameterValues]==========> 解密数据:{}" decryptParameter);
  • aesFlagtruecatchCommonBusinessException efalseerror"[modifyParameterValues]""[modifyParameterValues]==========>"}
  • /**
  • */
  • @Override
  • Enumeration getParameterNamesVector<>(()).elements}
  • name//重写getParameter,代表参数从当前类中的map获取
  • [];
  • addAllParameters otherParams//增加多个参数
  • addParameterObject//增加参数
  • {
  • }
  • 新建过滤器,在拦截器中调用自定义的参数包装器

     * Created by 吴蜀黍 on 2018-08-07 10:02
    
  • initFilterConfig filterConfigthrowsservletexception doFilterServletRequest servletRequestServletResponse servletResponseFilterChain filterChainIOException//使用自定义的参数包装器对参数进行处理
  • destroy}
  • web.xml中对过滤器进行配置

        <filter>
    
  • <filter-class>com.xxx.xxx.config.filter.ParameterFilter</filter-class>
  • <filter-mapping>
  • <!-- 过滤所有以.json结尾的资源-->
  • </filter-mapping>
  • AES加解密操作

     * Created by 吴蜀黍 on 2018-08-03 17:47
    
  • staticfinal CHARSET_NAME "UTF-8" AES_NAME "AES";
  • SecurityaddProviderBouncyCastleProvider/**
  • */
  • Exception exthrowCommonBusinessException"加密失败"}
  • * 解密
  • ());
  • 2.新建拦截器,验证Token以及解密的判断

  • preHandle httpServletRequestHttpServletResponse httpServletResponse handler//如果不是映射到方法直接通过
  • aesSuccess BooleanparseBooleanhttpServletRequestgetParameter));
  • //获取客户端上传Token
  • (!TokenUtilsverificationToken()))MSG_TOKEN_INVALID;
  • * 验证失败 发送消息
  • //对验证失败的返回信息进行加密
  • "[sendMsg]" writerprintclose();
  • }
  • 在spring中对拦截注册

    <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
    
  • <!-- 拦截所有请求 -->
  • <!-- 需排除拦截的地址 -->
  • <beanclass"com.xxx.xxx.config.interceptor.Asynchandlerinterceptor"/>
  • </mvc:interceptors>
  • Token的验证

     * Describe:Token帮助类
    
  • **/
  • TokenUtils * 验证Token
  • * @param token 客户端上传Token
  • * @return boolean
  • verificationToken tokenMap mapTypessaleEquals getTokenmapTypes));
  • List mapKes ArrayList<>();
  • ||
  • CollectionsmapKesStringBuilder sb StringBuilder();
  • sbappend//加上时间戳,去除所有空格 进行MD5加密
  • }
  • 3.对返回数据进行加密处理,新建JSON转换器继承自阿里的FastJsonHttpMessageConverter

     * Created by 吴蜀黍 on 2018-08-07 13:57
    
  • HttpMessageNotWritableExceptionOutputStreamoutgetBody"[writeInternal]======>返回明文数据:{}" jsonString//对返回数据进行AES加密
  • ();
  • spring中对JSON转换器进行配置

    <mvc:message-converters>
  • "com.xxx.xxx.config.converter.JsonMessageConverter">
  • <list>
  • application/json</value>
  • </list>
  • "features">
  • <!-- 认的意思就是不配置这个属性,配置了就不是认了 -->
  • WriteMapNullValue</value>
  • WriteDateUseDateFormat</value>
  • </property>
  • </mvc:message-converters>
  • 三、测试

    1.控制器

     * Created by 吴蜀黍 on 2018-08-08 11:13
    
  • @RequestMapping"/test"TestController"/test.json"@ResponseBody
  • createSuccessObj"测试成功"}
  • 2.测试结果

    客户端

    服务端 
    后台自动加解密模块中,原本是打算都在JSON转换器中处理,通过readInternal()解密,再通过writeInternal()加密,奈何调试的过程中总会出现一些未知错误,如有相关大神,请帮忙指点迷津!通过过滤器来处理参数有些大材小用的意思,如果哪位有更好的方案和处理方式欢迎留言,感激不尽!!! 


    四、客户端JS下载

    客户端JS下载,密码:qxql

    作者:吴蜀黍 
    链接https://www.jianshu.com/p/4b136750bdea 

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。