|
@@ -0,0 +1,188 @@
|
|
|
|
+package org.diagbot.graph.encryption;
|
|
|
|
+
|
|
|
|
+import java.security.InvalidKeyException;
|
|
|
|
+import java.security.Key;
|
|
|
|
+import java.security.NoSuchAlgorithmException;
|
|
|
|
+import java.security.SecureRandom;
|
|
|
|
+import java.security.spec.InvalidKeySpecException;
|
|
|
|
+import java.util.regex.Matcher;
|
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
+
|
|
|
|
+import javax.crypto.Cipher;
|
|
|
|
+import javax.crypto.SecretKey;
|
|
|
|
+import javax.crypto.SecretKeyFactory;
|
|
|
|
+import javax.crypto.spec.DESKeySpec;
|
|
|
|
+
|
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
|
+
|
|
|
|
+public class DESUtil {
|
|
|
|
+
|
|
|
|
+ //算法名称
|
|
|
|
+ public static final String KEY_ALGORITHM = "DES";
|
|
|
|
+ //算法名称/加密模式/填充方式
|
|
|
|
+ //DES共有四种工作模式-->>ECB:电子密码本模式、CBC:加密分组链接模式、CFB:加密反馈模式、OFB:输出反馈模式
|
|
|
|
+ public static final String CIPHER_ALGORITHM = "DES/ECB/NoPadding";
|
|
|
|
+
|
|
|
|
+ public static final String KEY_LANTONE = "langtong20190102";
|
|
|
|
+ public static final String padding = "n";
|
|
|
|
+ private static int bit = 8;
|
|
|
|
+
|
|
|
|
+ private static String reglower = "^[a-z]+$";
|
|
|
|
+ private static Pattern patlower = Pattern.compile(reglower);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ *
|
|
|
|
+ * 生成密钥key对象
|
|
|
|
+ * @param KeyStr 密钥字符串
|
|
|
|
+ * @return 密钥对象
|
|
|
|
+ * @throws InvalidKeyException
|
|
|
|
+ * @throws NoSuchAlgorithmException
|
|
|
|
+ * @throws InvalidKeySpecException
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ private static SecretKey keyGenerator(String keyStr) throws Exception {
|
|
|
|
+ byte input[] = HexString2Bytes(keyStr);
|
|
|
|
+ DESKeySpec desKey = new DESKeySpec(input);
|
|
|
|
+ //创建一个密匙工厂,然后用它把DESKeySpec转换成
|
|
|
|
+ SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
|
|
|
+ SecretKey securekey = keyFactory.generateSecret(desKey);
|
|
|
|
+ return securekey;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static int parse(char c) {
|
|
|
|
+ if (c >= 'a') return (c - 'a' + 10) & 0x0f;
|
|
|
|
+ if (c >= 'A') return (c - 'A' + 10) & 0x0f;
|
|
|
|
+ return (c - '0') & 0x0f;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 从十六进制字符串到字节数组转换
|
|
|
|
+ public static byte[] HexString2Bytes(String hexstr) {
|
|
|
|
+ byte[] b = new byte[hexstr.length() / 2];
|
|
|
|
+ int j = 0;
|
|
|
|
+ for (int i = 0; i < b.length; i++) {
|
|
|
|
+ char c0 = hexstr.charAt(j++);
|
|
|
|
+ char c1 = hexstr.charAt(j++);
|
|
|
|
+ b[i] = (byte) ((parse(c0) << 4) | parse(c1));
|
|
|
|
+ }
|
|
|
|
+ return b;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 加密数据
|
|
|
|
+ * @param data 待加密数据
|
|
|
|
+ * @param key 密钥
|
|
|
|
+ * @return 加密后的数据
|
|
|
|
+ */
|
|
|
|
+ public static String encrypt(String data, String key) {
|
|
|
|
+ byte[] results = new byte[1];
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ Key deskey = keyGenerator(key);
|
|
|
|
+ // 实例化Cipher对象,它用于完成实际的加密操作
|
|
|
|
+ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
|
|
|
+ SecureRandom random = new SecureRandom();
|
|
|
|
+ // 初始化Cipher对象,设置为加密模式
|
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, deskey, random);
|
|
|
|
+
|
|
|
|
+ int size = data.getBytes().length % bit;
|
|
|
|
+ for (int i = 0; i < bit-size; i++) {
|
|
|
|
+ data = data.concat(" ");
|
|
|
|
+ }
|
|
|
|
+ results = cipher.doFinal(data.getBytes());
|
|
|
|
+ // 该部分是为了与加解密在线测试网站(http://tripledes.online-domain-tools.com/)的十六进制结果进行核对
|
|
|
|
+ for (int i = 0; i < results.length; i++) {
|
|
|
|
+ System.out.print(results[i] + " ");
|
|
|
|
+ }
|
|
|
|
+ System.out.println();
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex) {
|
|
|
|
+ ex.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ // 执行加密操作。加密后的结果通常都会用Base64编码进行传输
|
|
|
|
+// return Base64.encodeBase64String(results);
|
|
|
|
+
|
|
|
|
+ return getHash(results);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 解密数据
|
|
|
|
+ * @param data 待解密数据
|
|
|
|
+ * @param key 密钥
|
|
|
|
+ * @return 解密后的数据
|
|
|
|
+ */
|
|
|
|
+ public static String decrypt(String data, String key) throws Exception {
|
|
|
|
+ Key deskey = keyGenerator(key);
|
|
|
|
+ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
|
|
|
+ //初始化Cipher对象,设置为解密模式
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, deskey);
|
|
|
|
+
|
|
|
|
+ byte[] bytes = deHash(data);
|
|
|
|
+ // 执行解密操作
|
|
|
|
+// return new String(cipher.doFinal(Base64.decodeBase64(data)));
|
|
|
|
+ return new String(cipher.doFinal(bytes));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将加密后的数据转换成16进制
|
|
|
|
+ *
|
|
|
|
+ * @param encryptbytes
|
|
|
|
+ */
|
|
|
|
+ public static String getHash(byte[] encryptbytes) {
|
|
|
|
+
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
+ StringBuilder hex = new StringBuilder();
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ for (byte b : encryptbytes) {
|
|
|
|
+
|
|
|
|
+ if (b<0) {
|
|
|
|
+ hex.append(String.format("%02x", b));
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ hex.append(String.format("%02X", b));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex) {
|
|
|
|
+ ex.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ finally {
|
|
|
|
+ return hex.toString();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将16进制的加密数据转换成byte数组
|
|
|
|
+ *
|
|
|
|
+ * @param hash
|
|
|
|
+ */
|
|
|
|
+ public static byte[] deHash(String hash) {
|
|
|
|
+
|
|
|
|
+ byte[] bytes = new byte[hash.length()/2];
|
|
|
|
+ String a,b;
|
|
|
|
+ Matcher mat_a, mat_b;
|
|
|
|
+ try {
|
|
|
|
+ for (int i=0; i<bytes.length; i++) {
|
|
|
|
+ a = hash.substring(i*2,i*2+1);
|
|
|
|
+ b = hash.substring(i*2+1, i*2+2);
|
|
|
|
+
|
|
|
|
+ mat_a = patlower.matcher(a);
|
|
|
|
+ mat_b = patlower.matcher(b);
|
|
|
|
+ if (mat_a.find() || mat_b.find()) {
|
|
|
|
+ bytes[i] = (byte)((Integer.parseInt(a, 16)*16 + Integer.parseInt(b, 16) -256) & 0xFF);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ bytes[i] = (byte)((Integer.parseInt(a, 16)*16 + Integer.parseInt(b, 16)) & 0xFF);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex) {
|
|
|
|
+ ex.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ finally {
|
|
|
|
+ return bytes;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|