| 
					
				 | 
			
			
				@ -0,0 +1,176 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				package com.yihu.jw.care.util; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.tomcat.util.codec.binary.Base64; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.bouncycastle.jce.provider.BouncyCastleProvider; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.json.JSONObject; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.slf4j.Logger; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.slf4j.LoggerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import javax.crypto.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import javax.crypto.spec.IvParameterSpec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import javax.crypto.spec.SecretKeySpec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import java.io.UnsupportedEncodingException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import java.security.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 * Created with IntelliJ IDEA. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 * @Author: yeshijie 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 * @Date: 2021/9/6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 * @Description: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				public class OnenetPushUtil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static Logger logger = LoggerFactory.getLogger(OnenetPushUtil.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static MessageDigest mdInst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    static { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            mdInst = MessageDigest.getInstance("MD5"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            Security.addProvider(new BouncyCastleProvider()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } catch (NoSuchAlgorithmException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            e.printStackTrace(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 功能描述:在OneNet平台配置数据接收地址时,平台会发送URL&token验证请求<p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *          使用此功能函数验证token 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param msg 请求参数 <msg>的值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param nonce 请求参数 <nonce>的值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param signature 请求参数 <signature>的值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param token OneNet平台配置页面token的值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return token检验成功返回true;token校验失败返回false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    public static boolean checkToken(String msg,String nonce,String signature, String token) throws UnsupportedEncodingException { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        byte[] paramB = new byte[token.length() + 8 + msg.length()]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        System.arraycopy(token.getBytes(), 0, paramB, 0, token.length()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        System.arraycopy(nonce.getBytes(), 0, paramB, token.length(), 8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        System.arraycopy(msg.getBytes(), 0, paramB, token.length() + 8, msg.length()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        String sig =  com.sun.org.apache.xerces.internal.impl.dv.util.Base64.encode(mdInst.digest(paramB)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        logger.info("url&token validation: result {},  detail receive:{} calculate:{}", sig.equals(signature.replace(' ','+')),signature,sig); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return sig.equals(signature.replace(' ','+')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 功能描述: 检查接收数据的信息摘要是否正确。<p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *          方法非线程安全。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param obj 消息体对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param token OneNet平台配置页面token的值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    public static boolean checkSignature(BodyObj obj, String token)  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        //计算接受到的消息的摘要 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        //token长度 + 8B随机字符串长度 + 消息长度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        byte[] signature = new byte[token.length() + 8 + obj.getMsg().toString().length()]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        System.arraycopy(token.getBytes(), 0, signature, 0, token.length()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        System.arraycopy(obj.getNonce().getBytes(), 0, signature, token.length(), 8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        System.arraycopy(obj.getMsg().toString().getBytes(), 0, signature, token.length() + 8, obj.getMsg().toString().length()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        String calSig = Base64.encodeBase64String(mdInst.digest(signature)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        logger.info("check signature: result:{}  receive sig:{},calculate sig: {}",calSig.equals(obj.getMsgSignature()),obj.getMsgSignature(),calSig); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return calSig.equals(obj.getMsgSignature()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *  功能描述 解密消息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param obj 消息体对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param encodeKey OneNet平台第三方平台配置页面为用户生成的AES的BASE64编码格式秘钥 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @throws NoSuchPaddingException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @throws NoSuchAlgorithmException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @throws InvalidAlgorithmParameterException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @throws InvalidKeyException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @throws BadPaddingException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @throws IllegalBlockSizeException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    public static String decryptMsg(BodyObj obj, String encodeKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        byte[] encMsg = Base64.decodeBase64(obj.getMsg().toString()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        byte[] aeskey = Base64.decodeBase64(encodeKey + "="); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        SecretKey secretKey = new SecretKeySpec(aeskey, 0, 32, "AES"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        Cipher cipher = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(aeskey, 0, 16)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        byte[] allmsg = cipher.doFinal(encMsg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        byte[] msgLenBytes = new byte[4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        System.arraycopy(allmsg, 16, msgLenBytes, 0, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        int msgLen = getMsgLen(msgLenBytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        byte[] msg = new byte[msgLen]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        System.arraycopy(allmsg, 20, msg, 0, msgLen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return new String(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 功能描述 解析数据推送请求,生成code>BodyObj</code>消息对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param body 数据推送请求body部分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param encrypted 表征是否为加密消息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return  生成的<code>BodyObj</code>消息对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    public static BodyObj resolveBody(String body, boolean encrypted) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        JSONObject jsonMsg = new JSONObject(body); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        BodyObj obj = new BodyObj(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        obj.setNonce(jsonMsg.getString("nonce")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        obj.setMsgSignature(jsonMsg.getString("msg_signature")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        if (encrypted) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (!jsonMsg.has("enc_msg")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            obj.setMsg(jsonMsg.getString("enc_msg")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (!jsonMsg.has("msg")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            obj.setMsg(jsonMsg.get("msg")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return obj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static int getMsgLen(byte[] arrays) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        int len = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        len += (arrays[0] & 0xFF) << 24; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        len += (arrays[1] & 0xFF) << 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        len += (arrays[2] & 0xFF) << 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        len += (arrays[3] & 0xFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    public static class BodyObj { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        private Object msg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        private String nonce; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        private String msgSignature; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        public Object getMsg() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return msg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        public void setMsg(Object msg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            this.msg = msg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        public String getNonce() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return nonce; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        public void setNonce(String nonce) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            this.nonce = nonce; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        public String getMsgSignature() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return msgSignature; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        public void setMsgSignature(String msgSignature) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            this.msgSignature = msgSignature; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        public String toString(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return "{ \"msg\":"+this.msg+",\"nonce\":"+this.nonce+",\"signature\":"+this.msgSignature+"}"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				} 
			 |