In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "WeChat Mini Programs interface encryption how to achieve", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Next let the editor to take you to learn "WeChat Mini Programs interface encryption how to achieve" it!
All the interface parameters requested by Mini Program in the scenario must be encrypted, the data returned by the backend must also be encrypted, and Token verification is added.
First, Mini Program end function preparation 1. Download a Js version of the aesUtil.js source code.
two。 Download a Js version of the md5.js source code.
3. The code for encryption and decryption in pulic.js is as follows, in which the offset of secret key and secret key should be the same as that of the background.
Var CryptoJS = require ('aesUtil.js'); / / reference AES source code js
Var md5 = require ('md5.js')
Var key = CryptoJS.enc.Utf8.parse ("76CAA1C88F7F8D1D"); / / hexadecimal number as the secret key
Var iv = CryptoJS.enc.Utf8.parse ('91129048100F0494'); / / hexadecimal number as secret key offset
/ / decryption method
Function Decrypt (word) {
Var encryptedHexStr = CryptoJS.enc.Hex.parse (word)
Var srcs = CryptoJS.enc.Base64.stringify (encryptedHexStr)
Var decrypt = CryptoJS.AES.decrypt (srcs, key, {
Iv: iv
Mode: CryptoJS.mode.CBC
Padding: CryptoJS.pad.Pkcs7
});
Var decryptedStr = decrypt.toString (CryptoJS.enc.Utf8)
Return decryptedStr.toString ()
}
/ / encryption method
Function Encrypt (word) {
Var srcs = CryptoJS.enc.Utf8.parse (word)
Var encrypted = CryptoJS.AES.encrypt (srcs, key, {
Iv: iv
Mode: CryptoJS.mode.CBC
Padding: CryptoJS.pad.Pkcs7
});
Return encrypted.ciphertext.toString () .toUpperCase ()
}
/ / expose the API
Module.exports.Decrypt = Decrypt
Module.exports.Encrypt = Encrypt
4. Encrypt the parameters and decrypt the returned data in the network request help class.
Var aes = require ('.. / utils/public.js') var md5 = require (".. / utils/md5.js"). / * Network request * / function request (method, loading, url, params, success, fail) {var url = BASE_URL + url;// request parameter to JSON string var jsonStr = JSON.stringify (params); console.log (url + 'params= >' + jsonStr) / / generate Tokenvar token = productionToken (params) according to specific rules / / encryption request parameter var aesData = aes.Encrypt (jsonStr) console.log ('request = > plaintext parameter:' + jsonStr) console.log ('request = > encryption parameter:' + aesData)... wx.request ({url: url,method: method,header: {'Content-Type':' application/x-www-form-urlencoded Charset=utf-8','Token': token}, data: {aesData: aesData}, / / data: params,success: function (res) {/ / determine whether the request result is successful or not if (res.statusCode = = 200 & & res.data! ='& res.data! = null) {/ / decrypt the returned data console.log ('return = > encrypted data:' + res.data); var result = aes.Decrypt (res.data); console.log ('return = > plaintext data:' + result) Success (JSON.parse (result))} else {fail ()}}, fail: function (res) {fail ()},})} the rules for generating Token. [the rules for generating Token can be defined according to the specific business logic. The rule I use here is to take its value according to the alphabetical order of the request parameters and add the current timestamp before MD5 encryption]
/ * generate Token*/function productionToken (params) {var obj = util.objKeySort (params); var value =''; for (var item in obj) {value + = obj [item];} / / add the current timestamp value + = util.getTokenDate (new Date ()) / / remove all spaces value = value.replace (/\ stimestamp g, ") / / encode value = encodeURI (value) for UTF-8; / / encrypt value = md5.hex_md5 (value) return value with MD5 code } / / util's sorting function function objKeySort (obj) {/ / first uses the keys method of the Object built-in class to obtain the property names of the object to be sorted, and then uses the sort method on the Array prototype to sort the obtained property names. Newkey is an array var newkey = Object.keys (obj). Sort (); / / create a new object to store sorted key-value pairs var newObj = {}; / / traverse the newkey array for (var I = 0; I)
< newkey.length; i++) {//向新创建的对象中按照排好的顺序依次增加键值对newObj[newkey[i]] = obj[newkey[i]];}//返回排好序的新对象return newObj;}二、服务端功能编写由于初学SpringMVC,使用的方式不一定是最优最好的,如有不妥善之处,请各位看官多多指教 思路: 通过过滤器拦截请求参数,通过自定义参数包装器对参数进行解密。 在拦截器获取请求的Token并生成服务器端Token进行验证。 对返回参数通过JSON转换器进行加密处理。 1.重写HttpServletRequestWrapper,在自定义的HttpServletRequestWrapper 中对参数进行处理 /*** Describe:请求参数包装器 主要作用的过滤参数并解密* Created by 吴蜀黍 on 2018-08-07 09:37**/@Slf4jpublic class ParameterRequestWrapper extends HttpServletRequestWrapper { private Map params = new HashMap(); @SuppressWarnings("unchecked")public ParameterRequestWrapper(HttpServletRequest request) {// 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似super(request);//将参数表,赋予给当前的Map以便于持有request中的参数this.params.putAll(request.getParameterMap());this.modifyParameterValues();} //重载一个构造方法public ParameterRequestWrapper(HttpServletRequest request, Map extendParams) {this(request);addAllParameters(extendParams);//这里将扩展参数写入参数表} private void modifyParameterValues() {//将parameter的值去除空格后重写回去 //获取加密数据String aesParameter = getParameter(Constants.NetWork.AES_DATA);log.debug("[modifyParameterValues]==========>Encrypted data: {} ", aesParameter); / decrypted String decryptParameter = null;try {decryptParameter = AesUtils.decrypt (aesParameter, Constants.AES.AES_KEY); log.debug (" [modifyParameterValues] = > decrypted data: {} ", decryptParameter); Map map = JSON.parseObject (decryptParameter); Set set = map.keySet (); for (String key: set) {params.put (key, new String [] {String.valueOf (key)});} aesFlag (true) } catch (CommonBusinessException e) {aesFlag (false); log.error ("[modifyParameterValues]", e); log.debug ("[modifyParameterValues] = >", e);}} / * * decryption success flag * / private void aesFlag (boolean flag) {params.put (Constants.NetWork.AES_SUCCESS, new String [] {String.valueOf (flag)});} @ Overridepublic Map getParameterMap () {/ / return super.getParameterMap (); return params } @ Overridepublic Enumeration getParameterNames () {return new Vector (params.keySet ()). Elements ();} @ Overridepublic String getParameter (String name) {/ / override getParameter, which means the parameter gets String [] values = params.get (name) from the map in the current class; if (values = = null | | values.length = 0) {return null;} return values [0];} public String [] getParameterValues (String name) {/ / Ibid return params.get (name) } public void addAllParameters (Map otherParams) {/ / add multiple parameters for (Map.Entry entry: otherParams.entrySet ()) {addParameter (entry.getKey (), entry.getValue ());}} public void addParameter (String name, Object value) {/ / add parameter if (value! = null) {if (value instanceof String []) {params.put (name, (String [] value);} else if (value instanceof String) {params.put (name, new String [] {(String) value})) } else {params.put (name, new String [] {String.valueOf (value)});} create a new filter and call a custom parameter wrapper in the interceptor
/ * Describe: request parameter filter * Created by Wu on 2018-08-07 10:02**/@Slf4jpublic class ParameterFilter implements Filter {@ Overridepublic void init (FilterConfig filterConfig) throws ServletException {} @ Overridepublic void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {/ / use a custom parameter wrapper to process parameters ParameterRequestWrapper requestWrapper = new ParameterRequestWrapper ((HttpServletRequest) servletRequest); filterChain.doFilter (requestWrapper, servletResponse) } @ Overridepublic void destroy () {}} web.xml configure the filter
ParameterFiltercom.xxx.xxx.config.filter.ParameterFilterparameterFilter*.jsonAES encryption and decryption operation
/ * Describe:AES encryption * Created by Wu on 2018-08-03 17:47**/public class AesUtils {private static final String CHARSET_NAME = "UTF-8"; private static final String AES_NAME = "AES"; private static final String ALGORITHM = "AES/CBC/PKCS7Padding"; private static final String IV = Constants.AES.AES_IV; static {Security.addProvider (new BouncyCastleProvider ()) } / * encryption * / public static String encrypt (@ NotNull String content, @ NotNull String key) throws CommonBusinessException {try {Cipher cipher = Cipher.getInstance (ALGORITHM); SecretKeySpec keySpec = new SecretKeySpec (key.getBytes (CHARSET_NAME), AES_NAME); AlgorithmParameterSpec paramSpec = new IvParameterSpec (IV.getBytes ()); cipher.init (Cipher.ENCRYPT_MODE, keySpec, paramSpec); return ParseSystemUtil.parseByte2HexStr (cipher.doFinal (content.getBytes (CHARSET_NAME);} catch (Exception ex) {throw new CommonBusinessException (encryption failure) }} / * decryption * / public static String decrypt (@ NotNull String content, @ NotNull String key) throws CommonBusinessException {try {Cipher cipher = Cipher.getInstance (ALGORITHM); SecretKeySpec keySpec = new SecretKeySpec (key.getBytes (CHARSET_NAME), AES_NAME); AlgorithmParameterSpec paramSpec = new IvParameterSpec (IV.getBytes ()); cipher.init (Cipher.DECRYPT_MODE, keySpec, paramSpec); return new String (Objects.requireNonNull (ParseSystemUtil.parseHexStr2Byte (content), CHARSET_NAME) } catch (Exception ex) {throw new CommonBusinessException ("decryption failed");}} 2. Create a new interceptor to verify Token and decryption judgment
@ Overridepublic boolean preHandle (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {/ / if not mapped to the method directly through if (! (handler instanceof HandlerMethod)) {return true;} / / determine whether the decryption of the request parameters in the parameter wrapper is successful boolean aesSuccess = Boolean.parseBoolean (httpServletRequest.getParameter (Constants.NetWork.AES_SUCCESS)); if (! aesSuccess) {this.sendMsg (Constants.NetWork.CODE_DECRYPTION_FAILURE, Constants.NetWork.MEG_AES_FAIL, httpServletResponse); return false } / / get client upload TokenString token = httpServletRequest.getHeader (Constants.NetWork.TOKEN_HEAD_KEY); if (StringUtils.isNullOrEmpty (token)) {sendMsg (Constants.NetWork.CODE_TOKEN_INVALID, Constants.NetWork.MSG_TOKEN_EMPTY, httpServletResponse); return false;} / / verify the validity of Token if (! TokenUtils.verificationToken (token, httpServletRequest.getParameterMap () {sendMsg (Constants.NetWork.CODE_TOKEN_INVALID, Constants.NetWork.MSG_TOKEN_INVALID, httpServletResponse); return false;} return true } / * send a message for verification failure * / private void sendMsg (String msgCode, String msg, HttpServletResponse httpServletResponse) throws IOException {httpServletResponse.setContentType ("application/json; charset=utf-8"); PrintWriter writer = httpServletResponse.getWriter (); String jsonString = JSON.toJSONString (StandardResult.create (msgCode, msg)); try {/ / encrypt the returned information for verification failure jsonString = AesUtils.encrypt (jsonString, Constants.AES.AES_KEY);} catch (CommonBusinessException e) {e.printStackTrace (); jsonString = null Log.error ("[sendMsg]", e);} writer.print (jsonString); writer.close (); httpServletResponse.flushBuffer ();} register the interceptor in spring
Verification of Token
/ * Describe:Token help class * Created by Uncle on 2018-08-04 14:48**/@Slf4jpublic class TokenUtils {/ * verify Token** @ param token client upload Token* @ param mapTypes request parameter set * @ return boolean*/public static boolean verificationToken (String token, Map mapTypes) {try {return StringUtils.saleEquals (token, getToken (mapTypes));} catch (UnsupportedEncodingException e) {log.error ("[verificationToken]", e); return false }} / * generate Token*/private static String getToken (Map mapTypes) throws UnsupportedEncodingException {List mapKes = new ArrayList () through client request parameters; for (Object obj: mapTypes.keySet ()) {String value = String.valueOf (obj); / / remove encryption related keyif (StringUtils.saleEquals (value, Constants.NetWork.AES_SUCCESS) in the parameters | | StringUtils.saleEquals (value, Constants.NetWork.AES_DATA) {break;} mapKes.add (value);} / sort keyCollections.sort (mapKes) StringBuilder sb = new StringBuilder (); for (String key: mapKes) {String value = ((String []) mapTypes.get (key)) [0]; sb.append (value);} / with a timestamp, MD5 string string = sb.append (DateUtils.getDateStr (DateUtils.FORMAT_YYYYMMDDHH)). ToString (). Replace (","); return MD5.getMD5 (URLEncoder.encode (string, "UTF-8"));}} 3. Encrypt the returned data, and the new JSON converter is inherited from Ali's FastJsonHttpMessageConverter.
/ * Describe:Json converter will return data encryption * Created by Wu on 2018-08-07 13:57**/@Slf4jpublic class JsonMessageConverter extends FastJsonHttpMessageConverter {@ Overrideprotected void writeInternal (Object object, HttpOutputMessage outputMessage) throws IOException,HttpMessageNotWritableException {OutputStream out = outputMessage.getBody (); try {String jsonString = JSON.toJSONString (object); log.debug ("[writeInternal] = > return plaintext data: {}" + jsonString) / / AES encryption jsonString = AesUtils.encrypt (jsonString, Constants.AES.AES_KEY) for returned data; log.debug ("[writeInternal] = > return encrypted data: {}" + jsonString); out.write (jsonString.getBytes ());} catch (CommonBusinessException e) {e.printStackTrace (); log.error ("[writeInternal] = >", e);} out.close ();} configure JSON converter in spring
Text/html;charset=UTF-8application/jsonapplication/xml;charset=UTF-8WriteMapNullValueWriteNullNumberAsZeroWriteNullListAsEmptyWriteNullStringAsEmptyWriteNullBooleanAsFalseWriteDateUseDateFormat here, I believe that everyone on the "WeChat Mini Programs interface encryption how to achieve" have a deeper understanding, might as well to the actual operation of it! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.