钉钉/微信开放平台加解密(钉钉/微信加密解密) 钉钉/微信AES 加密解密
2018-03-15 14:47
681 查看
1.钉钉开放平台加解密方法
2.钉钉jsapi签名工具类
3.PKCS7算法的加密填充
4.钉钉开放平台加解密异常类
5.加解密工具类
import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayOutputStream; import java.nio.charset.Charset; import java.security.MessageDigest; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** * 钉钉开放平台加解密方法 * 在ORACLE官方网站下载JCE无限制权限策略文件 * JDK6的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html * JDK7的下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html */ public class DingTalkEncryptor { private static final Charset CHARSET = Charset.forName("utf-8"); private static final Base64 base64 = new Base64(); private byte[] aesKey; private String token; private String corpId; private static final Integer AES_ENCODE_KEY_LENGTH = Integer.valueOf(43); private static final Integer RANDOM_LENGTH = Integer.valueOf(16); public DingTalkEncryptor(String token, String encodingAesKey, String corpId) throws DingTalkEncryptException { if(null != encodingAesKey && encodingAesKey.length() == AES_ENCODE_KEY_LENGTH.intValue()) { this.token = token; this.corpId = corpId; this.aesKey = Base64.decodeBase64(encodingAesKey + "="); } else { throw new DingTalkEncryptException(Integer.valueOf(900004)); } } public Map<String, String> getEncryptedMap(String plaintext, Long timeStamp, String nonce) throws DingTalkEncryptException { if(null == plaintext) { throw new DingTalkEncryptException(Integer.valueOf(900001)); } else if(null == timeStamp) { throw new DingTalkEncryptException(Integer.valueOf(900002)); } else if(null == nonce) { throw new DingTalkEncryptException(Integer.valueOf(900003)); } else { String encrypt = this.encrypt(DingTalkUtils.getRandomStr(RANDOM_LENGTH.intValue()), plaintext); String signature = this.getSignature(this.token, String.valueOf(timeStamp), nonce, encrypt); Map<String, String> resultMap = new HashMap(); resultMap.put("msg_signature", signature); resultMap.put("encrypt", encrypt); resultMap.put("timeStamp", String.valueOf(timeStamp)); resultMap.put("nonce", nonce); return resultMap; } } public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg) throws DingTalkEncryptException { String signature = this.getSignature(this.token, timeStamp, nonce, encryptMsg); if(!signature.equals(msgSignature)) { throw new DingTalkEncryptException(Integer.valueOf(900006)); } else { String result = this.decrypt(encryptMsg); return result; } } private String encrypt(String random, String plaintext) throws DingTalkEncryptException { try { byte[] randomBytes = random.getBytes(CHARSET); byte[] plainTextBytes = plaintext.getBytes(CHARSET); byte[] lengthByte = DingTalkUtils.int2Bytes(plainTextBytes.length); byte[] corpidBytes = this.corpId.getBytes(CHARSET); ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); byteStream.write(randomBytes); byteStream.write(lengthByte); byteStream.write(plainTextBytes); byteStream.write(corpidBytes); byte[] padBytes = PKCS7Padding.getPaddingBytes(byteStream.size()); byteStream.write(padBytes); byte[] unencrypted = byteStream.toByteArray(); byteStream.close(); Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES"); IvParameterSpec iv = new IvParameterSpec(this.aesKey, 0, 16); cipher.init(1, keySpec, iv); byte[] encrypted = cipher.doFinal(unencrypted); String result = base64.encodeToString(encrypted); return result; } catch (Exception var15) { throw new DingTalkEncryptException(Integer.valueOf(900007)); } } private String decrypt(String text) throws DingTalkEncryptException { byte[] originalArr; byte[] networkOrder; try { Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES"); IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(this.aesKey, 0, 16)); cipher.init(2, keySpec, iv); networkOrder = Base64.decodeBase64(text); originalArr = cipher.doFinal(networkOrder); } catch (Exception var9) { throw new DingTalkEncryptException(Integer.valueOf(900008)); } String plainText; String fromCorpid; try { byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr); networkOrder = Arrays.copyOfRange(bytes, 16, 20); int plainTextLegth = DingTalkUtils.bytes2int(networkOrder); plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET); fromCorpid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET); } catch (Exception var8) { throw new DingTalkEncryptException(Integer.valueOf(900009)); } if(!fromCorpid.equals(this.corpId)) { throw new DingTalkEncryptException(Integer.valueOf(900010)); } else { return plainText; } } public String getSignature(String token, String timestamp, String nonce, String encrypt) throws DingTalkEncryptException { try { String[] array = new String[]{token, timestamp, nonce, encrypt}; Arrays.sort(array); StringBuffer sb = new StringBuffer(); for(int i = 0; i < 4; ++i) { sb.append(array[i]); } String str = sb.toString(); MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update(str.getBytes()); byte[] digest = md.digest(); StringBuffer hexstr = new StringBuffer(); String shaHex = ""; for(int i = 0; i < digest.length; ++i) { shaHex = Integer.toHexString(digest[i] & 255); if(shaHex.length() < 2) { hexstr.append(0); } hexstr.append(shaHex); } return hexstr.toString(); } catch (Exception var13) { throw new DingTalkEncryptException(Integer.valueOf(900006)); } } }
2.钉钉jsapi签名工具类
import java.security.MessageDigest; import java.util.Formatter; /** * 钉钉jsapi签名工具类 */ public class DingTalkJsApiSingnature { public DingTalkJsApiSingnature() { } public static String getJsApiSingnature(String url, String nonce, Long timeStamp, String jsTicket) throws DingTalkEncryptException { String plainTex = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonce + "×tamp=" + timeStamp + "&url=" + url; String signature = ""; try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(plainTex.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); return signature; } catch (Exception var7) { throw new DingTalkEncryptException(Integer.valueOf(900006)); } } private static String byteToHex(byte[] hash) { Formatter formatter = new Formatter(); byte[] var2 = hash; int var3 = hash.length; for(int var4 = 0; var4 < var3; ++var4) { byte b = var2[var4]; formatter.format("%02x", new Object[]{Byte.valueOf(b)}); } String result = formatter.toString(); formatter.close(); return result; } public static void main(String[] args) throws Exception { String url = "http://10.62.53.138:3000/jsapi"; String nonce = "abcdefgh"; Long timeStamp = Long.valueOf(1437027269927L); String tikcet = "zHoQdGJuH0ZDebwo7sLqLzHGUueLmkWCC4RycYgkuvDu3eoROgN5qhwnQLgfzwEXtuR9SDzh6BdhyVngzAjrxV"; System.err.println(getJsApiSingnature(url, nonce, timeStamp, tikcet)); } }
3.PKCS7算法的加密填充
import java.nio.charset.Charset; import java.util.Arrays; /* * PKCS7算法的加密填充 */ public class PKCS7Padding { private static final Charset CHARSET = Charset.forName("utf-8"); private static final int BLOCK_SIZE = 32; public PKCS7Padding() { } public static byte[] getPaddingBytes(int count) { int amountToPad = 32 - count % 32; if(amountToPad == 0) { amountToPad = 32; } char padChr = chr(amountToPad); c561 String tmp = new String(); for(int index = 0; index < amountToPad; ++index) { tmp = tmp + padChr; } return tmp.getBytes(CHARSET); } public static byte[] removePaddingBytes(byte[] decrypted) { int pad = decrypted[decrypted.length - 1]; if(pad < 1 || pad > 32) { pad = 0; } return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); } private static char chr(int a) { byte target = (byte)(a & 255); return (char)target; } }
4.钉钉开放平台加解密异常类
import java.util.HashMap; import java.util.Map; /** * 钉钉开放平台加解密异常类 */ public class DingTalkEncryptException extends Exception { /**成功**/ public static final int SUCCESS = 0; /**加密明文文本非法**/ public final static int ENCRYPTION_PLAINTEXT_ILLEGAL = 900001; /**加密时间戳参数非法**/ public final static int ENCRYPTION_TIMESTAMP_ILLEGAL = 900002; /**加密随机字符串参数非法**/ public final static int ENCRYPTION_NONCE_ILLEGAL = 900003; /**不合法的aeskey**/ public final static int AES_KEY_ILLEGAL = 900004; /**签名不匹配**/ public final static int SIGNATURE_NOT_MATCH = 900005; /**计算签名错误**/ public final static int COMPUTE_SIGNATURE_ERROR = 900006; /**计算加密文字错误**/ public final static int COMPUTE_ENCRYPT_TEXT_ERROR = 900007; /**计算解密文字错误**/ public final static int COMPUTE_DECRYPT_TEXT_ERROR = 900008; /**计算解密文字长度不匹配**/ public final static int COMPUTE_DECRYPT_TEXT_LENGTH_ERROR = 900009; /**计算解密文字corpid不匹配**/ public final static int COMPUTE_DECRYPT_TEXT_CORPID_ERROR = 900010; private static final long serialVersionUID = -7009381945707655052L; private static Map<Integer,String> msgMap = new HashMap<Integer,String>(); static{ msgMap.put(SUCCESS,"成功"); msgMap.put(ENCRYPTION_PLAINTEXT_ILLEGAL,"加密明文文本非法"); msgMap.put(ENCRYPTION_TIMESTAMP_ILLEGAL,"加密时间戳参数非法"); msgMap.put(ENCRYPTION_NONCE_ILLEGAL,"加密随机字符串参数非法"); msgMap.put(SIGNATURE_NOT_MATCH,"签名不匹配"); msgMap.put(COMPUTE_SIGNATURE_ERROR,"签名计算失败"); msgMap.put(AES_KEY_ILLEGAL,"不合法的aes key"); msgMap.put(COMPUTE_ENCRYPT_TEXT_ERROR,"计算加密文字错误"); msgMap.put(COMPUTE_DECRYPT_TEXT_ERROR,"计算解密文字错误"); msgMap.put(COMPUTE_DECRYPT_TEXT_LENGTH_ERROR,"计算解密文字长度不匹配"); msgMap.put(COMPUTE_DECRYPT_TEXT_CORPID_ERROR,"计算解密文字corpid或者suiteKey不匹配"); } public Integer code; public DingTalkEncryptException(Integer exceptionCode){ super(msgMap.get(exceptionCode)); this.code = exceptionCode; } }
5.加解密工具类
package com.maycur.dingtalk.common.util.aes; import java.util.Random; /** * 加解密工具类 */ public class DingTalkUtils { public DingTalkUtils() { } public static String getRandomStr(int count) { String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for(int i = 0; i < count; ++i) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); } public static byte[] int2Bytes(int count) { byte[] byteArr = new byte[]{(byte)(count >> 24 & 255), (byte)(count >> 16 & 255), (byte)(count >> 8 & 255), (byte)(count & 255)}; return byteArr; } public static int bytes2int(byte[] byteArr) { int count = 0; for(int i = 0; i < 4; ++i) { count <<= 8; count |= byteArr[i] & 255; } return count; } }
相关文章推荐
- C#实现微信AES-128-CBC加密数据的解密
- 微信小程序AES加密解密相关
- 微信小程序-AES加密解密
- thinkphp微信开发(消息加密解密)
- JAVA的AES加密解密在windows上测试正常,但Linux服务器上却有异常!
- PHP AES双向加密解密(128位)
- AES 加密 解密(Hex编码解码)
- AES加密解密
- Java AES加密解密的简单实现方法
- JavaScript前端和Java后端的AES加密和解密
- windows中使用Python进行AES加密解密-加密解密功能实现
- Aes加密/解密示例
- python 加密解密(base64, AES)
- AES加密解密
- aes加密解密文件,以及计算文件的效验值,附带字符串加密解密
- NET实现RSA AES DES 字符串 加密解密以及SHA1 MD5加密
- android jni c++ aes cbc 128加密解密
- AES 加密/解密备忘
- Java-AES加密解密
- java,AES加密,解密