En primer lugar, el modo de desarrollo de las cuentas de WeChat Enterprise se divide en: modo de edición (modo normal) y modo de desarrollo (modo de devolución de llamada) . En el modo de edición, solo puede hacer menús personalizados simples y responder automáticamente mensajes. Para realizar otras funciones, debe activar el modo de desarrollador.
1. Modo de edición y modo de desarrollo para procesar mensajes
1. En el modo de edición, todos los procesos comerciales se configuran en el servidor WeChat y se procesan por él.
2. Modo de desarrollo, los mensajes se procesan a través de servidores de terceros, y finalmente se envían mensajes a los usuarios a través de servidores WeChat.
El modo de desarrollo puede procesar más mensajes que el modo de edición, por lo que primero debe habilitar el modo de desarrollo para desarrollar más funciones.
2. Se inicia el modelo de desarrollo
En el modo de devolución de llamada, las empresas no solo pueden llamar activamente a la interfaz de número empresarial, sino que también recibir mensajes o eventos de los usuarios. La información recibida se codifica en formato de datos XML, UTF8, y se encripta en AES .
1. Después de encender el modo de devolución de llamada, los parámetros deben configurarse de la siguiente manera:
La URL es el servlet a acceder, y el token y el codingaSKey se obtienen aleatoriamente, pero deben ser consistentes con el proyecto.
2. Verifique la validez de la URL
Cuando envíe la información anterior, el número empresarial enviará una solicitud GET a la URL llena. La solicitud GET tiene cuatro parámetros. La empresa debe procesar el código de urldecode al obtenerlo , de lo contrario, la verificación no tendrá éxito.
3. Código
Clase de coreservlet1
Public Class CoreServlet1 extiende httpservlet {private static final long SerialVersionUid = 4440739483644821986l; String stoken = "weixincourse"; String Scorpid = "WXE510946434680DAB"; String sencodingaeskey = "djlyzxgkiwresiw2vnv9dsr7hss7uswdfnwa8q1ove1"; Public void doget (HTTPServLetRequest Solicitud, respuesta httpservletResponse) lanza ServletException, ioException {wxbizmsgcrypt wxcpt; Pruebe {wxcpt = new WxBizmsgCrypt (Stoken, SenCodingaesKey, ScorpID); String sverifymsgsig = request.getParameter ("msg_signature"); String SverifyTimestamp = request.getParameter ("Timestamp"); Cadena sverifynonce = request.getParameter ("nonce"); String sverifyeChostr = request.getParameter ("ECHOSTR"); Cadena Sechostr; sechostr = wxcpt.verifyUrl (Sverifymsgsig, SverifytimeStamp, SverifyNonce, SverifyeChostr); System.out.println ("VerifyUrl ECHOSTR:" + SECHOSTR); PrintWriter out = Response.getWriter (); out.print (sechostr); out.close (); out = nulo; } catch (aesexception e1) {e1.printstackTrace (); }}} Herramientas:
/*** Código de muestra para encriptar y descifrar mensajes enviados a cuentas públicas por plataformas públicas. * * @Copyright Copyright (c) 1998-2014 Tencent Inc. * /// ----------------------------------------------------------------------------------------------------------------------------------------------------------- com.qq.weixin.mp.aes; import java.nio.charset.charset; import java.util.Arrays; import java.util.random; import javax.crypto.cipher; import javax.crypto.spec.ivparameterspec; import javax.crypto.sec.secretkeyspec; org.apache.commons.codec.binary.base64;/*** Proporciona una interfaz de cifrado y descifrado (cadena codificada por UTF8) para recibir y enviar mensajes a la plataforma pública. * <ol> * <li> Respuesta de terceros a mensajes cifrados a la plataforma pública </li> * * <li> El tercero recibe mensajes enviados por la plataforma pública para verificar la seguridad de los mensajes y descifrar los mensajes. </li> * </ol> * Descripción: Excepción java.security.invalidkeyException: solución al tamaño de clave ilegal * <ol> * <li> Descargar JCE INLIMITED POLICY FILE en el sitio web oficial (la dirección de descarga de JDK7: * http://www.oracle.com/technetwork/java/javase/downloads/jce-7 download-432124.html </li> * <li> DECOMPRESS después de descargar, puede ver local_policy.jar, us_export_policy.jar y readMe.txt </li> * <ri> %Jre_home %/lib/directorio de seguridad para sobrescribir el archivo original </li> * <li> Si JDK está instalado, coloque los dos archivos jar en el directorio de %jdk_home %/jre/lib/de seguridad para sobrescribir el archivo original </li> * </ol> */public class WXBizmsgcrypt {Charset Charset = Charset = Charset. base64 = nuevo Base64 (); Información de error de la excepción */ public wxbizmsgCrypt (token de cadena, string codingaeskey, string corpid) lanza aesexception {if (codingaeskey.length ()! = 43) {tirar nueva aeSexception (aesexception.illegalaeskey); } this.token = token; this.corpid = corpid; aeskey = base64.DecodeBase64 (Encodingaeskey + "="); } /*** descifrar el texto cifrado. ** @param text El texto cifrado que necesita ser descifrado* @return El texto sin formato obtenido por descifrado* @throws aesexception aes no pudo descifrar*/ string decrypt (texto de cadena) arroja aSexception {byte [] original; Pruebe {// Establezca el modo de descifrado en el modo AES CBC CIPHER CIPHER = cipher.getInstance ("AES/CBC/NOPADDING"); Secretkeyspec key_spec = new SecretKeSpec (Aeskey, "AES"); IvParameterspec IV = nuevo IVParameterspec (Arrays.CopyOfRange (aeskey, 0, 16)); cipher.init (cipher.decrypt_mode, key_spec, iv); // use base64 para decodificar el byte de texto cifrado [] cifrado = base64.decodeBase64 (texto); // Decrypt original = cipher.dofinal (encriptado); } catch (Exception e) {E.PrintStackTrace (); arrojar una nueva aesexception (aesexception.decryptaesError); } String xmlContent, from_corpid; Pruebe {// elimine el carácter del complemento byte [] bytes = pkcs7encoder.decode (original); // Strings aleatorios separados de 16 bits, endianness de red y byte corpid [] networker = arrays.copyOfrange (bytes, 16, 20); int xmllength = RecovernetWorkByTesOrder (NetworkOrge); xmlContent = new String (arrays.copyOfRange (bytes, 20, 20 + xmllength), charset); from_corpid = new String (arrays.copyOfRange (bytes, 20 + xmllength, bytes.length), charset); } catch (Exception e) {E.PrintStackTrace (); arrojar una nueva aesexception (aesexception.legalbuffer); } // Caso donde Corpid es diferente if (! from_corpid.equals (corpid)) {tire nueva aesexception (aesexception.validateCorpiderRor); } return xmlContent; } /** * Verifique URL * @param msgsignature String String, correspondiente a los parámetros de URL msg_signature * @param timestamp timestamp, correspondiente a los parámetros de la URL timestamp * @param nonce string aleator, correspondiente a los parámetros de url nonce * @param ataMtr string aleatory, correspondiente a los parámetros de url echostr * * @ @@retneturno La ejecución de AesException falló, verifique el código de error y la información de error específica de la excepción */ public String VerifyUrl (String MSGSignature, String Timestamp, String Nonce, String ECHOSTR) lanza AesException {String Signature = Sha1.getSha1 (Token, Timestamp, Nonce, ECHOSTR); if (! Signature.equals (msgsignature)) {tire nueva aesexception (aesexception.ValidatesignatureError); } Result de cadena = Decrypt (ECHOSTR); resultado de retorno; }} /*** Código de muestra para encriptar y descifrar mensajes enviados a cuentas públicas por plataformas públicas. * * @Copyright Copyright (c) 1998-2014 Tencent Inc. * /// ----------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- @param encrypt cifradoxt* @return segura firma* @throws aesexception*/ public static string getSha1 (string token, string timestamp, string nonce, string cifript) lanza aesexception {try {string [] array = new String [] {token, timestamp, nonce, encrypt}; StringBuffer sb = new StringBuffer (); // String Sort Arrays.sort (Array); para (int i = 0; i <4; i ++) {sb.append (matriz [i]); } String str = sb.ToString (); // SHA1 Generación de la firma MessageGest MD = MessageDigest.getInstance ("SHA-1"); md.update (str.getbytes ()); byte [] digest = md.digest (); StringBuffer hexstr = new StringBuffer (); Cadena shahex = ""; for (int i = 0; i <digest.length; i ++) {shahex = integer.tohexString (digest [i] & 0xff); if (shahex.length () <2) {hexstr.append (0); } hexstr.append (Shahex); } return hexstr.ToString (); } catch (Exception e) {E.PrintStackTrace (); tirar nueva Aesexception (aesexception.cutegutesignatureError); }}} clase PKCS7Encoder {static charset charset = charset.forname ("utf-8"); static int block_size = 32;/ *** Eliminar el carácter del complemento del texto sin formato descryado** @param descifrado el texto sin formato descifrado* @return sin texto después de eliminar el carácter de relleno*/ static byte [] decode (byte [] descrypted) {int) if (pad <1 || almoh> 32) {pad = 0; } matriz de retorno.copyOfRange (descifrado, 0, descifrado.length - pad); }} 3. Resumen
La empresa verifica la solicitud a través del parámetro msg_signature. Si se confirma que la solicitud GET proviene del número empresarial, entonces la aplicación empresarial descifra el parámetro ECHOSTR y devuelve el texto de la libertad de prueba de ECHOSTR tal como está (citado no se puede agregar), entonces la verificación de acceso entra en efecto y el modo de devolución de llamada se puede habilitar. Después de encender, se implementarán algunas funciones una tras otra, ¡así que estad atentos!
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.