zoukankan      html  css  js  c++  java
  • JAVA -> 数据加密和解密 留存

       来源网站:https://www.cnblogs.com/itgungnir/p/6210936.html

    1、Base64工具类(可逆):

    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Base64加解密算法
     * </p>
     * Base64加密算法:<br/>
     * 1、获取字符串中每个字符的ASCII码;<br/>
     * 2、按照每3个8bit的字符为一组来分组,即每组24bit;<br/>
     * 3、将这24bit划分成4个6bit的4个单位,每个单位前面添加2个0,得到4个8bit的单位;<br/>
     * 4、将每个8bit的单位转换成十进制数字,对照Base64编码表找到对应的字符进行拼接,得到最终的加密后的字符串。<br/>
     * </p>
     * Base64解密算法:<br/>
     * 1、读入4个字符,对照Base64编码表找到字符对应的索引,生成4个6为的值;<br/>
     * 2、将这4个6为的值拼接起来,形成一个24为的值;<br/>
     * 3、将这个24位的值按照8位一组截断成3个8位的值;<br/>
     * 4、对照ASCII表找到这三个8位的值对应的字符,即解码后的字符。<br/>
     * </p>
     * 注意事项:<br/>
     * 1、被编码的字符必须是8bit的,即必须在ASCII码范围内,中文不行;<br/>
     * 2、如果被编码的字符长度不是3的倍数,则在最后添加1或2个0,对应的输出字符为“=”;
     * 3、给定一个字符串,用Base64方法对其进行加密后解密,得到的结果就不是开始时候的字符串了。<br/>
     */
    public class BASE64Util {
        private static final Map<Integer, Character> base64CharMap = new HashMap<>();
        private static final String base64CharString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    
        private static BASE64Util instance;
    
        private BASE64Util() {
            for (int i = 0; i < base64CharString.length(); i++) {
                char c = base64CharString.charAt(i);
                base64CharMap.put(new Integer(i), new Character(c));
            }
        }
    
        public static BASE64Util getInstance() {
            if (instance == null) {
                synchronized (BASE64Util.class) {
                    if (instance == null) {
                        instance = new BASE64Util();
                    }
                }
            }
            return instance;
        }
    
        /**
         * This method is used to encode a normal string to base64 string @param
         * origin The String to be encoded @return The String after encoded.
         */
        public String encode(String origin) {
            if (origin == null) {
                return null;
            }
            if (origin.length() == 0) {
                return "";
            }
            int length = origin.length();
            String binaryString = "";
            // to binary String
            for (int i = 0; i < length; i++) {
                int ascii = origin.charAt(i);
                String binaryCharString = Integer.toBinaryString(ascii);
                while (binaryCharString.length() < 8) {
                    binaryCharString = "0" + binaryCharString;
                }
                binaryString += binaryCharString;
            }
    
            // to base64 index
            int beginIndex = 0;
            int endIndex = beginIndex + 6;
            String base64BinaryString = "";
            String charString = "";
            while ((base64BinaryString = binaryString.substring(beginIndex, endIndex)).length() > 0) {
                // if length is less than 6, add "0".
                while (base64BinaryString.length() < 6) {
                    base64BinaryString += "0";
                }
                int index = Integer.parseInt(base64BinaryString, 2);
                char base64Char = base64CharMap.get(index);
                charString = charString + base64Char;
                beginIndex += 6;
                endIndex += 6;
                if (endIndex >= binaryString.length()) {
                    endIndex = binaryString.length();
                }
                if (endIndex < beginIndex) {
                    break;
                }
            }
            if (length % 3 == 2) {
                charString += "=";
            }
            if (length % 3 == 1) {
                charString += "==";
            }
            return charString;
        }
    
        public String decode(String encodedString) {
            if (encodedString == null) {
                return null;
            }
            if (encodedString.length() == 0) {
                return "";
            }
            // get origin base64 String
            String origin = encodedString.substring(0, encodedString.indexOf("="));
            String equals = encodedString.substring(encodedString.indexOf("="));
    
            String binaryString = "";
            // convert base64 string to binary string
            for (int i = 0; i < origin.length(); i++) {
                char c = origin.charAt(i);
                int ascii = base64CharString.indexOf(c);
                String binaryCharString = Integer.toBinaryString(ascii);
                while (binaryCharString.length() < 6) {
                    binaryCharString = "0" + binaryCharString;
                }
                binaryString += binaryCharString;
            }
            // the encoded string has 1 "=", means that the binary string has append
            // 2 "0"
            if (equals.length() == 1) {
                binaryString = binaryString.substring(0, binaryString.length() - 2);
            }
            // the encoded string has 2 "=", means that the binary string has append
            // 4 "0"
            if (equals.length() == 2) {
                binaryString = binaryString.substring(0, binaryString.length() - 4);
            }
    
            // convert to String
            String charString = "";
            String resultString = "";
            int beginIndex = 0;
            int endIndex = beginIndex + 8;
            while ((charString = binaryString.substring(beginIndex, endIndex)).length() == 8) {
                int ascii = Integer.parseInt(charString, 2);
                resultString += (char) ascii;
                beginIndex += 8;
                endIndex += 8;
                if (endIndex > binaryString.length()) {
                    break;
                }
            }
            return resultString;
        }
    }
    

      

    2、MD5工具类(不可逆):

    import java.security.MessageDigest;
    
    import javax.crypto.KeyGenerator;
    import javax.crypto.Mac;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class MD5Util {
        public static final String MD5 = "MD5";
        public static final String HmacMD5 = "HmacMD5";
        public static final String charset = null; // 编码格式;默认null为GBK
    
        private static MD5Util instance;
    
        private MD5Util() {
        }
    
        // 单例
        public static MD5Util getInstance() {
            if (instance == null) {
                synchronized (MD5Util.class) {
                    if (instance == null) {
                        instance = new MD5Util();
                    }
                }
            }
            return instance;
        }
    
        /**
         * 使用 MD5 方法加密(无密码)
         */
        public String encode(String res) {
            try {
                MessageDigest md = MessageDigest.getInstance(MD5);
                byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
                return BASE64Util.getInstance().encode(md.digest(resBytes).toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 使用 MD5 方法加密(可以设密码)
         */
        public String encode(String res, String key) {
            try {
                SecretKey sk = null;
                if (key == null) {
                    KeyGenerator kg = KeyGenerator.getInstance(HmacMD5);
                    sk = kg.generateKey();
                } else {
                    byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                    sk = new SecretKeySpec(keyBytes, HmacMD5);
                }
                Mac mac = Mac.getInstance(HmacMD5);
                mac.init(sk);
                byte[] result = mac.doFinal(res.getBytes());
                return BASE64Util.getInstance().encode(result.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

      

    3、SHA1工具类(不可逆):

    import java.security.MessageDigest;
    
    import javax.crypto.KeyGenerator;
    import javax.crypto.Mac;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    /**
     * 使用 SHA1 方法进行加密<br/>
     * SHA1方法加密是不可逆的,不能解密,要想解密就必须使用暴力解密<br/>
     * <p/>
     * 方法中的 res 参数:原始的数据<br/>
     * 方法中的 key 参数:密钥,可以随便写<br/>
     */
    public class SHA1Util {
        public static final String SHA1 = "SHA1";
        public static final String HmacSHA1 = "HmacSHA1";
        public static final String charset = null; // 编码格式;默认null为GBK
    
        private static SHA1Util instance;
    
        private SHA1Util() {
        }
    
        // 单例
        public static SHA1Util getInstance() {
            if (instance == null) {
                synchronized (SHA1Util.class) {
                    if (instance == null) {
                        instance = new SHA1Util();
                    }
                }
            }
            return instance;
        }
    
        /**
         * 使用 SHA1 方法加密(无密码)
         */
        public String encode(String res) {
            try {
                MessageDigest md = MessageDigest.getInstance(SHA1);
                byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
                return BASE64Util.getInstance().encode(md.digest(resBytes).toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 使用 SHA1 方法加密(可以设密码)
         */
        public String encode(String res, String key) {
            try {
                SecretKey sk = null;
                if (key == null) {
                    KeyGenerator kg = KeyGenerator.getInstance(HmacSHA1);
                    sk = kg.generateKey();
                } else {
                    byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                    sk = new SecretKeySpec(keyBytes, HmacSHA1);
                }
                Mac mac = Mac.getInstance(HmacSHA1);
                mac.init(sk);
                byte[] result = mac.doFinal(res.getBytes());
                return BASE64Util.getInstance().encode(result.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

      

    4、AES工具类(可逆):

    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class AESUtil {
        public static final String AES = "AES";
        public static final String charset = null; // 编码格式;默认null为GBK
        public static final int keysizeAES = 128;
    
        private static AESUtil instance;
    
        private AESUtil() {
        }
    
        // 单例
        public static AESUtil getInstance() {
            if (instance == null) {
                synchronized (MD5Util.class) {
                    if (instance == null) {
                        instance = new AESUtil();
                    }
                }
            }
            return instance;
        }
    
        /**
         * 使用 AES 进行加密
         */
        public String encode(String res, String key) {
            return keyGeneratorES(res, AES, key, keysizeAES, true);
        }
    
        /**
         * 使用 AES 进行解密
         */
        public String decode(String res, String key) {
            return keyGeneratorES(res, AES, key, keysizeAES, false);
        }
    
        // 使用KeyGenerator双向加密,DES/AES,注意这里转化为字符串的时候是将2进制转为16进制格式的字符串,不是直接转,因为会出错
        private String keyGeneratorES(String res, String algorithm, String key, int keysize, boolean isEncode) {
            try {
                KeyGenerator kg = KeyGenerator.getInstance(algorithm);
                if (keysize == 0) {
                    byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                    kg.init(new SecureRandom(keyBytes));
                } else if (key == null) {
                    kg.init(keysize);
                } else {
                    byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                    kg.init(keysize, new SecureRandom(keyBytes));
                }
                SecretKey sk = kg.generateKey();
                SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm);
                Cipher cipher = Cipher.getInstance(algorithm);
                if (isEncode) {
                    cipher.init(Cipher.ENCRYPT_MODE, sks);
                    byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
                    return parseByte2HexStr(cipher.doFinal(resBytes));
                } else {
                    cipher.init(Cipher.DECRYPT_MODE, sks);
                    return new String(cipher.doFinal(parseHexStr2Byte(res)));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        // 将二进制转换成16进制
        private String parseByte2HexStr(byte buf[]) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < buf.length; i++) {
                String hex = Integer.toHexString(buf[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
    
        // 将16进制转换为二进制
        private byte[] parseHexStr2Byte(String hexStr) {
            if (hexStr.length() < 1)
                return null;
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; i++) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
    }
    

      

    5、DES工具类(可逆):

    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class DESUtil {
        public static final String DES = "DES";
        public static final String charset = null; // 编码格式;默认null为GBK
        public static final int keysizeDES = 0;
    
        private static DESUtil instance;
    
        private DESUtil() {
        }
    
        // 单例
        public static DESUtil getInstance() {
            if (instance == null) {
                synchronized (MD5Util.class) {
                    if (instance == null) {
                        instance = new DESUtil();
                    }
                }
            }
            return instance;
        }
    
        /**
         * 使用 DES 进行加密
         */
        public String encode(String res, String key) {
            return keyGeneratorES(res, DES, key, keysizeDES, true);
        }
    
        /**
         * 使用 DES 进行解密
         */
        public String decode(String res, String key) {
            return keyGeneratorES(res, DES, key, keysizeDES, false);
        }
    
        // 使用KeyGenerator双向加密,DES/AES,注意这里转化为字符串的时候是将2进制转为16进制格式的字符串,不是直接转,因为会出错
        private String keyGeneratorES(String res, String algorithm, String key, int keysize, boolean isEncode) {
            try {
                KeyGenerator kg = KeyGenerator.getInstance(algorithm);
                if (keysize == 0) {
                    byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                    kg.init(new SecureRandom(keyBytes));
                } else if (key == null) {
                    kg.init(keysize);
                } else {
                    byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                    kg.init(keysize, new SecureRandom(keyBytes));
                }
                SecretKey sk = kg.generateKey();
                SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm);
                Cipher cipher = Cipher.getInstance(algorithm);
                if (isEncode) {
                    cipher.init(Cipher.ENCRYPT_MODE, sks);
                    byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
                    return parseByte2HexStr(cipher.doFinal(resBytes));
                } else {
                    cipher.init(Cipher.DECRYPT_MODE, sks);
                    return new String(cipher.doFinal(parseHexStr2Byte(res)));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        // 将二进制转换成16进制
        private String parseByte2HexStr(byte buf[]) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < buf.length; i++) {
                String hex = Integer.toHexString(buf[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
    
        // 将16进制转换为二进制
        private byte[] parseHexStr2Byte(String hexStr) {
            if (hexStr.length() < 1)
                return null;
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; i++) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
    }

    6、XOR(异或加密)工具类(可逆):

    public class XORUtil {
        private static XORUtil instance;
    
        private XORUtil() {
        }
    
        // 单例
        public static XORUtil getInstance() {
            if (instance == null) {
                synchronized (XORUtil.class) {
                    if (instance == null) {
                        instance = new XORUtil();
                    }
                }
            }
            return instance;
        }
    
        /**
         * 对一个数字进行异或加解密
         */
        public int code(int res, String key) {
            return res ^ key.hashCode();
        }
    
        /**
         * 异或加密
         */
        public String encode(String res, String key) {
            byte[] bs = res.getBytes();
            for (int i = 0; i < bs.length; i++) {
                bs[i] = (byte) ((bs[i]) ^ key.hashCode());
            }
            return parseByte2HexStr(bs);
        }
    
        /**
         * 异或解密
         */
        public String decode(String res, String key) {
            byte[] bs = parseHexStr2Byte(res);
            for (int i = 0; i < bs.length; i++) {
                bs[i] = (byte) ((bs[i]) ^ key.hashCode());
            }
            return new String(bs);
        }
    
        // 将二进制转换成16进制
        private String parseByte2HexStr(byte buf[]) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < buf.length; i++) {
                String hex = Integer.toHexString(buf[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
    
        // 将16进制转换为二进制
        private byte[] parseHexStr2Byte(String hexStr) {
            if (hexStr.length() < 1)
                return null;
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; i++) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
    }
    

      

    7、测试:

    public class Test {
        public static void main(String[] args) {
            int xorNum = 12345;
            String res = "I am the text to be encoded and decoded.";
            String key = "我是密钥key";
            System.out.println("-------------------------BASE64--------------------------");
            String base64_encodedStr = BASE64Util.getInstance().encode(res);
            System.out.println("加密:" + base64_encodedStr);
            System.out.println("解密:" + BASE64Util.getInstance().decode(base64_encodedStr));
            System.out.println("-------------------------MD5--------------------------");
            String md5_encodedStr = MD5Util.getInstance().encode(res);
            System.out.println("无密码加密:" + md5_encodedStr);
            System.out.println("有密码加密:" + MD5Util.getInstance().encode(md5_encodedStr, key));
            System.out.println("-------------------------SHA1--------------------------");
            String sha1_encodedStr = SHA1Util.getInstance().encode(res);
            System.out.println("无密码加密:" + sha1_encodedStr);
            System.out.println("有密码加密:" + SHA1Util.getInstance().encode(sha1_encodedStr, key));
            System.out.println("-------------------------AES--------------------------");
            String aes_encodedStr = AESUtil.getInstance().encode(res, key);
            System.out.println("加密:" + aes_encodedStr);
            System.out.println("解密:" + AESUtil.getInstance().decode(aes_encodedStr, key));
            System.out.println("-------------------------DES--------------------------");
            String des_encodedStr = DESUtil.getInstance().encode(res, key);
            System.out.println("加密:" + des_encodedStr);
            System.out.println("解密:" + DESUtil.getInstance().decode(des_encodedStr, key));
            System.out.println("-------------------------XOR--------------------------");
            String xor_encodedStr = XORUtil.getInstance().encode(res, key);
            System.out.println("文本加密:" + xor_encodedStr);
            System.out.println("文本解密:" + XORUtil.getInstance().decode(xor_encodedStr, key));
            int xor_encodedNum = XORUtil.getInstance().code(xorNum, key);
            System.out.println("数字加密:" + xor_encodedNum);
            System.out.println("数字解密:" + XORUtil.getInstance().code(xor_encodedNum, key));
        }
    }
    

      

    测试结果:

     测试结果

  • 相关阅读:
    新入行程序员考虑自己是否明白以下这8件事情
    程序猿品种总结你是哪一类?
    利用趣味漫画讲述云计算起源
    设计师遇到瓶颈时的五个解困惑建议
    可以帮助到我今后的程序员生涯的十分钟思考
    oc编程中继承的相关实例
    centos和ubuntu服务器Bash漏洞修复方法
    jQuery经典面试题精选
    phpstudy -sql服务器2008r2 -中控考勤机 -php 组合查询考勤
    bat 批处理测试局域网速度 两端电脑
  • 原文地址:https://www.cnblogs.com/niunafei/p/10882137.html
Copyright © 2011-2022 走看看