1. 程式人生 > >Java常見加密和解密演算法

Java常見加密和解密演算法

1:加密和解密輔助工具類:

/**
 * byte hex utility class
 **/
public class ByteHexUtils {

    private static final String HEX_STR = "0123456789ABCDEF";


    /**
     * @param hex
     * @return
     */
    public static byte[] hex2Bytes(String hex) {
        ByteBuffer bf = ByteBuffer.allocate(hex.length() / 2);
        for (int i = 0; i < hex.length(); i++) {
            String hexStr = hex.charAt(i) + "";
            i++;
            hexStr += hex.charAt(i);
            byte b = (byte) Integer.parseInt(hexStr, 16);
            bf.put(b);
        }
        return bf.array();
    }


    /**
     * @param bytes
     **/
    public static String bytes2Hex(byte[] bytes) {
        String result = "";
        String hex = "";
        for (int i = 0; i < bytes.length; i++) {
            //位元組高4位
            hex = String.valueOf(HEX_STR.charAt((bytes[i] & 0xF0) >> 4));
            //位元組低4位
            hex += String.valueOf(HEX_STR.charAt(bytes[i] & 0x0F));
            result += hex;  //+" "
        }
        return result;
    }

}

2:Base64加密和解密:

    /**
     * base64 utility class
     **/
     import sun.misc.BASE64Decoder;
     import sun.misc.BASE64Encoder;
     public class Base64Utils {

        /**
         * byte to base64
         **/
        public static String encode(byte[] bytes) {
            BASE64Encoder base64Encoder = new BASE64Encoder();
            return base64Encoder.encode(bytes);
        }

        /**
         * base64 to byte
         **/
        public static byte[] decode(String base64) throws IOException {
            BASE64Decoder base64Decoder = new BASE64Decoder();
            return base64Decoder.decodeBuffer(base64);
        }

        public static void main(String[] args) throws IOException {
            final String testString = "hello,i am chenkangxian,good night!";
            System.out.println(Base64Utils.encode(testString.getBytes()));
            String base64Str = "aGVsbG8saSBhbSBjaGVua2FuZ3hpYW4sZ29vZCBuaWdodCE=";
            System.out.println(new String(Base64Utils.decode(base64Str), Charset.defaultCharset()));
        }
    }

3:SHA1和MD5加密和解密:

  
    /**
     * digest utility class with MD5 and SHA-1
     **/
    public static class DigestsUtils {

        /**
         * 160位(16進位制字串: 40)
         **/
        private static final String SHA1 = "SHA-1";

        /**
         * 128位(16進位制字串: 32)
         **/
        private static final String MD5 = "MD5";

        /**
         * SHA-1; encrypt without (salt and iterations)
         *
         * @param bytes encrypt byte array
         **/
        public static byte[] sha1(byte[] bytes) {
            return digest(bytes, SHA1, (byte[]) null, 1);
        }

        /**
         * SHA-1; encrypt without iterations
         *
         * @param bytes encrypt byte array
         * @param salt  encrypt salt
         **/
        public static byte[] sha1(byte[] bytes, byte[] salt) {
            return digest(bytes, SHA1, salt, 1);
        }

        /**
         * SHA-1;
         *
         * @param bytes      encrypt byte array
         * @param salt       encrypt salt
         * @param iterations encrypt iterations
         **/
        public static byte[] sha1(byte[] bytes, byte[] salt, int iterations) {
            return digest(bytes, SHA1, salt, iterations);
        }

        /**
         * MD5
         **/
        public static byte[] md5(byte[] bytes) {
            return digest(bytes, MD5, (byte[]) null, 1);
        }

        /**
         * MD5
         **/
        public static byte[] md5(byte[] bytes, byte[] salt) {
            return digest(bytes, MD5, salt, 1);
        }

        /**
         * MD5
         **/
        public static byte[] md5(byte[] bytes, byte[] salt, int iterations) {
            return digest(bytes, MD5, salt, iterations);
        }


        /**
         * 對salt生成的位元組是平臺預設編碼
         *
         * @see Charset#defaultCharset()
         **/
        public static byte[] generateSalt() {
            return UUID.randomUUID().toString().getBytes();
        }


        /**
         * digest encode md5
         *
         * @param newStr     new str
         * @param oldMd5     old md5 bytes
         * @param salt       md5 salt
         * @param iterations md5 digest iterations
         * @see Arrays
         **/
        public static boolean decodeMd5(byte[] newStr, byte[] oldMd5, byte[] salt, int iterations) {
            return decode(MD5, newStr, oldMd5, salt, iterations);
        }


        /**
         * digest encode sha-1
         *
         * @param newStr     new str
         * @param oldSha1    old sha-1 bytes
         * @param salt       sha-1 salt
         * @param iterations sha-1 digest iterations
         * @see Arrays
         **/
        public static boolean decodeSha1(byte[] newStr, byte[] oldSha1, byte[] salt, int iterations) {
            return decode(SHA1, newStr, oldSha1, salt, iterations);
        }


        /**
         * digest encode
         *
         * @param newStr     new str
         * @param oldDigest  old digest bytes
         * @param salt       md5 salt
         * @param iterations md5 digest iterations
         * @see Arrays
         **/
        private static boolean decode(String algorithm, byte[] newStr, byte[] oldDigest, byte[] salt, int iterations) {
            if (MD5.equalsIgnoreCase(algorithm)) {
                byte[] newDigest = md5(newStr, salt, iterations);
                log.debug("encode new md5 digest: {}", ByteHexUtils.bytes2Hex(newDigest));
                if (Arrays.equals(newDigest, oldDigest)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                byte[] newDigest = sha1(newStr, salt, iterations);
                log.debug("encode new sha1 digest: {}", ByteHexUtils.bytes2Hex(newDigest));
                if (Arrays.equals(newDigest, oldDigest)) {
                    return true;
                } else {
                    return false;
                }
            }
        }


        /**
         * digest with salt and iterations
         **/
        private static byte[] digest(byte[] bytes, String algorithm, byte[] salt, int iterations) {
            try {
                MessageDigest e = MessageDigest.getInstance(algorithm);
                if (salt != null) {
                    e.update(salt);
                }
                byte[] result = e.digest(bytes);
                for (int i = 1; i < iterations; ++i) {
                    e.reset();
                    result = e.digest(result);
                }
                return result;
            } catch (GeneralSecurityException e) {
                e.printStackTrace();
            }
            return null;
        }

        public static void main(String[] args) {
            String testString = "123456";
            String salt = UUID.randomUUID().toString();
            byte[] md5 = DigestsUtils.md5(testString.getBytes(), salt.getBytes(), 1);
            System.out.println(ByteHexUtils.bytes2Hex(md5));
            if (DigestsUtils.decodeMd5("123456".getBytes(), md5, salt.getBytes(), 1)) {
                System.out.println("密碼正確");
            } else {
                System.out.println("密碼錯誤");
            }


            byte[] sha1 = DigestsUtils.sha1(testString.getBytes());
            System.out.println(ByteHexUtils.bytes2Hex(sha1));
            if (DigestsUtils.decodeSha1("123456".getBytes(), sha1, null, 1)) {
                System.out.println("密碼正確");
            } else {
                System.out.println("密碼錯誤");
            }
        }
    }

4:RSA加密和解密

在這裡插入程式碼片
```   /**
     * rsa utility class
     **/
    public static class RsaUtils {


        private static final String RSA = "RSA";

        //生成公鑰和私鑰

        /**
         * 首先初始化{@link KeyPairGenerator},並生成{@link KeyPair},
         * 得到{@link KeyPair},便可以通過getPublic和getPrivate分別獲取
         * 公鑰和私鑰.為了方便儲存,將其使用Base64編碼轉換為String型別的列印字元
         **/
        public static KeyPair getKeyPair() throws Exception {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA);
            //預設512,如果是1024位,需要到官網下載不限長度的加密jar包
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            return keyPair;
        }

        /**
         * get public key
         *
         * @see Base64Utils#encode(byte[])
         **/
        public static String getPublicKeyStr(KeyPair keyPair) {
            PublicKey publicKey = keyPair.getPublic();
            byte[] bytes = publicKey.getEncoded();
            return Base64Utils.encode(bytes);
        }

        /**
         * get primary key
         *
         * @see Base64Utils#encode(byte[])
         **/
        public static String getPrivateKeyStr(KeyPair keyPair) {
            PrivateKey privateKey = keyPair.getPrivate();
            byte[] bytes = privateKey.getEncoded();
            return Base64Utils.encode(bytes);
        }

        /**
         * 將String型別的金鑰轉換為PublicKey和PrivateKey物件
         **/
        public static PublicKey string2PublicKey(String publicKeyStr) throws Exception {
            byte[] keyBytes = Base64Utils.decode(publicKeyStr);
            //使用ASN.1為公鑰編碼
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA);
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            return publicKey;
        }


        /**
         * 將String型別的金鑰轉換為{@link PrivateKey}
         **/
        public static PrivateKey string2PrivateKey(String privateKeyStr) throws Exception {
            byte[] keyBytes = Base64Utils.decode(privateKeyStr);
            //使用ASN.1為私鑰編碼
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA);
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            return privateKey;
        }


        /**
         * 使用公鑰加密
         **/
        public static byte[] publicEncrypt(byte[] content, PublicKey publicKey) throws Exception {
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] bytes = cipher.doFinal(content);
            return bytes;
        }

        /**
         * 使用私鑰解密
         **/
        public static byte[] privateDecrypt(byte[] content, PrivateKey privateKey) throws Exception {
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] bytes = cipher.doFinal(content);
            return bytes;
        }

        public static void main(String[] args) throws Exception {
            final String testString = "1234567";

            //獲得金鑰對
            KeyPair keyPair = RsaUtils.getKeyPair();

            //獲得私鑰字串
            String privateKeyStr = RsaUtils.getPrivateKeyStr(keyPair);
            System.out.println("primary key string: " + privateKeyStr);
            System.out.println();

            //獲得公鑰字串
            String publicKeyStr = RsaUtils.getPublicKeyStr(keyPair);
            System.out.println("public key string: " + publicKeyStr);
            System.out.println();

            //獲取私鑰和公鑰
            PublicKey publicKey = RsaUtils.string2PublicKey(publicKeyStr);
            PrivateKey privateKey = RsaUtils.string2PrivateKey(privateKeyStr);
            System.out.println();

            //使用公鑰加密
            byte[] bytes = RsaUtils.publicEncrypt(testString.getBytes(), publicKey);
            System.out.println("RSA公鑰加密: " + Base64Utils.encode(bytes));
            System.out.println();

            //使用私鑰解密
            System.out.println("RSA私鑰解密: " + new String(RsaUtils.privateDecrypt(bytes, privateKey),
                    Charset.defaultCharset()));
        }
    }