Java加密工具類


加密工具類:

package group.hound.starter.core.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.util.StringUtils;

import group.hound.starter.core.exception.ContentNotFoundSaltException;
import group.hound.starter.core.exception.EncryptionException;

/**
 * <p>
 * 加解密工具類
 * </p>
 *
 * @author 廢柴 2018/9/13 星期四 11:56
 */
@SuppressWarnings("all")
public class EncryptionUtils {
    private static final String DEFAULT_CHARSET = "UTF-8";

    private EncryptionUtils() {
    }

    /**
     * MD5 非對稱加密
     */
    public static class MD5 {
        /**
         * MD5 加密
         *
         * @param content 加密內容
         * @return 加密結果
         */
        public static String encrypt(String content) {
            return DigestUtils.md5Hex(content);
        }

        /**
         * MD5 加密
         *
         * @param content 加密內容
         * @return 加密結果
         */
        public static String encrypt(byte[] content) {
            return DigestUtils.md5Hex(content);
        }

        /**
         * MD5 加密
         *
         * @param contentStream 加密內容
         * @return 加密結果
         */
        public static String encrypt(InputStream contentStream) {
            try {
                return DigestUtils.md5Hex(contentStream);
            } catch (IOException e) {
                throw new EncryptionException("MD5 encrypt failed!", e);
            }
        }
    }

    /**
     * AES 對稱加密
     */
    public static class AES {
        private static final String ALGORITHM = "AES";

        /**
         * 生成秘鑰
         */
        public static String generaterKey() {
            KeyGenerator keygen = null;
            try {
                keygen = KeyGenerator.getInstance(ALGORITHM);
            } catch (NoSuchAlgorithmException e) {
                throw new EncryptionException("AES generater Key failed!", e);
            }
            // 16 字節 == 128 bit
            keygen.init(128, new SecureRandom());
            SecretKey secretKey = keygen.generateKey();
            return Base64.getEncoder().encodeToString(secretKey.getEncoded());
        }

        /**
         * 生成密鑰
         */
        private static SecretKeySpec getSecretKeySpec(String secretKeyStr) {
            return new SecretKeySpec(Base64.getDecoder().decode(secretKeyStr), ALGORITHM);
        }

        /**
         * 加密
         */
        public static String encrypt(String content, String secretKey) {
            Key key = getSecretKeySpec(secretKey);
            try {
                // 創建密碼器
                Cipher cipher = Cipher.getInstance(ALGORITHM);
                // 初始化
                cipher.init(Cipher.ENCRYPT_MODE, key);
                return Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes(DEFAULT_CHARSET)));
            } catch (Exception e) {
                throw new EncryptionException("AES encrypt failed!", e);
            }
        }

        /**
         * 解密
         */
        public static String decrypt(String content, String secretKey) {
            Key key = getSecretKeySpec(secretKey);
            try {
                Cipher cipher = Cipher.getInstance(ALGORITHM);
                cipher.init(Cipher.DECRYPT_MODE, key);
                return new String(cipher.doFinal(Base64.getDecoder().decode(content)), StandardCharsets.UTF_8);
            } catch (Exception e) {
                throw new EncryptionException("AES decrypt failed!", e);
            }
        }
    }

    @FunctionalInterface
    interface WithSalt {
        /**
         * 加鹽
         *
         * @param content 加密內容
         * @param salt    鹽
         * @return 加鹽密文
         */
        String withSalt(String content, String salt);
    }

    private static final WithSalt DEFAULT_WITH_SALT = new WithSalt() {
        @Override
        public String withSalt(String content, String salt) {
            return content + salt;
        }
    };

    @FunctionalInterface
    interface WithoutSalt {
        /**
         * 加鹽
         *
         * @param content 加密內容
         * @param salt    鹽
         * @return 加鹽密文
         */
        String withoutSalt(String content, String salt);
    }

    private static final WithoutSalt DEFAULT_WITHOUT_SALT = new WithoutSalt() {
        @Override
        public String withoutSalt(String content, String salt) {
            if (!StringUtils.hasText(content)) {
                return content;
            }
            if (content.endsWith(salt)) {
                return content.substring(0, salt.length());
            }
            throw new ContentNotFoundSaltException(content, salt);
        }
    };

    /**
     * RSA 對稱加密
     */
    public static class RSA {
        private static final String ALGORITHM = "RSA";
        private static final String ALGORITHMS_SHA1 = "SHA1WithRSA";

        /**
         * 生成秘鑰對
         * throw {@link NoSuchAlgorithmException} 找不到算法異常
         *
         * @return first : 私鑰/second : 公鑰
         */
        public static Pair<String, String> generateKeyPair() {
            KeyPairGenerator keygen = null;
            try {
                keygen = KeyPairGenerator.getInstance(ALGORITHM);
            } catch (NoSuchAlgorithmException e) {
                throw new EncryptionException("RSA generate Key Pair failed!", e);
            }
            keygen.initialize(512, new SecureRandom());
            // 生成密鑰對
            KeyPair keyPair = keygen.generateKeyPair();
            return Pair.of(Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()),
                    Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));
        }

        /**
         * 生成秘鑰對
         *
         * @param keySize 密鑰大小
         *                throw {@link NoSuchAlgorithmException} 找不到算法異常
         * @return first : 私鑰/second : 公鑰
         */
        public static Pair<String, String> generateKeyPair(int keySize) {
            KeyPairGenerator keygen = null;
            try {
                keygen = KeyPairGenerator.getInstance(ALGORITHM);
            } catch (NoSuchAlgorithmException e) {
                throw new EncryptionException("RSA generate Key Pair failed!", e);
            }
            keygen.initialize(keySize, new SecureRandom());
            // 生成密鑰對
            KeyPair keyPair = keygen.generateKeyPair();
            return Pair.of(Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()),
                    Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));
        }

        /**
         * 獲取公鑰
         * <p>
         * throw {@link InvalidKeySpecException} 無效的 Key Spec
         * throw {@link NoSuchAlgorithmException} 找不到算法異常
         *
         * @param publicKey 公鑰
         * @return 公鑰
         */
        public static RSAPublicKey getPublicKey(String publicKey) {
            try {
                return (RSAPublicKey) KeyFactory.getInstance(ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey)));
            } catch (Exception e) {
                throw new EncryptionException("RSA get Public Key failed!", e);
            }
        }

        /**
         * 獲取私鑰
         * <p>
         * throw {@link InvalidKeySpecException} 無效的 Key Spec
         * throw {@link NoSuchAlgorithmException} 找不到算法異常
         *
         * @param privateKey 私鑰
         * @return 私鑰
         */
        public static RSAPrivateKey getPrivateKey(String privateKey) {
            try {
                return (RSAPrivateKey) KeyFactory.getInstance(ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
            } catch (Exception e) {
                throw new EncryptionException("RSA get Private Key failed!", e);
            }
        }

        /**
         * 私鑰簽名內容
         * <p>
         * throw {@link InvalidKeySpecException} 無效的 Key Spec
         * throw {@link NoSuchAlgorithmException} 無效的 Key
         * throw {@link UnsupportedEncodingException} 不支持的編碼
         * throw {@link SignatureException} 簽名異常
         * throw {@link NoSuchAlgorithmException} 無效的算法
         *
         * @param content    內容
         * @param privateKey 私鑰
         * @return 私鑰簽名
         */
        public static String sign(String content, String privateKey) {
            try {
                Signature signature = Signature.getInstance(ALGORITHMS_SHA1);
                signature.initSign(getPrivateKey(privateKey));
                signature.update(content.getBytes(DEFAULT_CHARSET));
                return Base64.getEncoder().encodeToString(signature.sign());
            } catch (Exception e) {
                throw new EncryptionException("RSA sign failed!", e);
            }
        }


        /**
         * 公鑰校驗簽名
         * <p>
         * throw {@link InvalidKeySpecException} 無效的 Key Spec
         * throw {@link NoSuchAlgorithmException} 無效的 Key
         * throw {@link UnsupportedEncodingException} 不支持的編碼
         * throw {@link SignatureException} 簽名異常
         * throw {@link NoSuchAlgorithmException} 無效的算法
         *
         * @param content   內容
         * @param sign      簽名
         * @param publicKey 公鑰
         * @return 是否匹配
         */
        public static boolean verify(String content, String sign, String publicKey) {
            try {
                Signature signature = Signature.getInstance(ALGORITHMS_SHA1);
                signature.initVerify(getPublicKey(publicKey));
                signature.update(content.getBytes(DEFAULT_CHARSET));
                return signature.verify(Base64.getDecoder().decode(sign));
            } catch (Exception e) {
                throw new EncryptionException("RSA verify failed!", e);
            }
        }

        /**
         * 使用公鑰或者私鑰加密
         * <p>
         * throw {@link InvalidKeyException} 無效的 Key
         * throw {@link UnsupportedEncodingException} 不支持的解碼
         * throw {@link BadPaddingException} 錯誤間隔異常
         * throw {@link IllegalBlockSizeException} 無效塊大小異常
         * throw {@link NoSuchPaddingException} 無效的監間距異常
         * throw {@link NoSuchAlgorithmException} 無效的算法
         *
         * @param content 內容
         * @param key     公鑰或者私鑰
         * @return 密文
         */
        public static String encrypt(String content, Key key) {
            try {
                Cipher cipher = Cipher.getInstance(ALGORITHM);
                cipher.init(Cipher.ENCRYPT_MODE, key);
                return Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes(DEFAULT_CHARSET)));
            } catch (Exception e) {
                throw new EncryptionException("RSA encrypt failed!", e);
            }
        }

        /**
         * 使用公鑰或者私鑰解密
         * <p>
         * throw {@link InvalidKeyException} 無效的 Key
         * throw {@link BadPaddingException} 錯誤間隔異常
         * throw {@link IllegalBlockSizeException} 無效塊大小異常
         * throw {@link NoSuchPaddingException} 無效的監間距異常
         * throw {@link NoSuchAlgorithmException} 無效的算法
         *
         * @param content 內容
         * @param key     公鑰或者私鑰
         * @return 明文
         */
        public static String decrypt(String content, Key key) {
            try {
                Cipher cipher = Cipher.getInstance(ALGORITHM);
                cipher.init(Cipher.DECRYPT_MODE, key);
                return new String(cipher.doFinal(Base64.getDecoder().decode(content)), StandardCharsets.UTF_8);
            } catch (Exception e) {
                throw new EncryptionException("RSA decrypt failed!", e);
            }
        }

        /**
         * 使用公鑰加鹽加密
         *
         * @param content   明文
         * @param publicKey 公鑰
         * @return 密文
         */
        public static String encrypt(String content, String publicKey) {
            return RSA.encrypt(content, null, publicKey, null);
        }

        /**
         * 使用公鑰加鹽加密
         *
         * @param content   明文
         * @param key       鹽
         * @param publicKey 公鑰
         * @return 密文
         */
        public static String encrypt(String content, String key, String publicKey) {
            return RSA.encrypt(content, key, publicKey, DEFAULT_WITH_SALT);
        }

        /**
         * 使用公鑰加鹽加密
         *
         * @param content   明文
         * @param key       鹽
         * @param publicKey 公鑰
         * @param withSalt  明文加鹽
         * @return 密文
         */
        public static String encrypt(String content, String key, String publicKey, WithSalt withSalt) {
            return RSA.encrypt(withSalt != null ? withSalt.withSalt(content, key) : content, getPublicKey(publicKey));
        }

        /**
         * 使用私鑰解密去鹽
         *
         * @param content    密文
         * @param privateKey 私鑰
         * @return 明文
         */
        public static String decrypt(String content, String privateKey) {
            return decrypt(content, null, privateKey, null);
        }

        /**
         * 使用私鑰解密去鹽
         *
         * @param content    密文
         * @param key        鹽
         * @param privateKey 私鑰
         * @return 明文
         */
        public static String decrypt(String content, String key, String privateKey) {
            return decrypt(content, key, privateKey, DEFAULT_WITHOUT_SALT);
        }

        /**
         * 使用私鑰解密去鹽
         *
         * @param content     密文
         * @param key         鹽
         * @param privateKey  私鑰
         * @param withoutSalt 解密內容去鹽
         * @return 明文
         */
        public static String decrypt(String content, String key, String privateKey, WithoutSalt withoutSalt) {
            return withoutSalt != null
                    ? withoutSalt.withoutSalt(decrypt(content, getPrivateKey(privateKey)), key)
                    : decrypt(content, getPrivateKey(privateKey));
        }
    }

    /**
     * RSA2 對稱加密
     */
    public static class RSA2 {
        private static final String ALGORITHMS_SHA256 = "SHA256WithRSA";

        /**
         * 生成秘鑰對
         * <p>
         * throw {@link NoSuchAlgorithmException} 找不到算法異常
         *
         * @return first : 私鑰/second : 公鑰
         */
        public static Pair<String, String> generateKeyPair() {
            return RSA.generateKeyPair();
        }

        /**
         * 獲取公鑰
         * <p>
         * throw {@link InvalidKeySpecException} 無效的 Key Spec
         * throw {@link NoSuchAlgorithmException} 找不到算法異常
         *
         * @param publicKey 公鑰
         * @return 公鑰
         */
        private static RSAPublicKey getPublicKey(String publicKey) {
            return RSA.getPublicKey(publicKey);
        }

        /**
         * 獲取私鑰
         * <p>
         * throw {@link InvalidKeySpecException} 無效的 Key Spec
         * throw {@link NoSuchAlgorithmException} 找不到算法異常
         *
         * @param privateKey 私鑰
         * @return 私鑰
         */
        private static RSAPrivateKey getPrivateKey(String privateKey) {
            return RSA.getPrivateKey(privateKey);
        }

        /**
         * 私鑰簽名內容
         * <p>
         * throw {@link InvalidKeySpecException} 無效的 Key Spec
         * throw {@link InvalidKeyException} 無效的 Key
         * throw {@link UnsupportedEncodingException} 不支持的編碼
         * throw {@link SignatureException} 簽名異常
         * throw {@link NoSuchAlgorithmException} 無效的算法
         *
         * @param content    內容
         * @param privateKey 私鑰
         * @return 私鑰簽名
         */
        public static String sign(String content, String privateKey) {
            try {
                Signature signature = Signature.getInstance(ALGORITHMS_SHA256);
                signature.initSign(getPrivateKey(privateKey));
                signature.update(content.getBytes(DEFAULT_CHARSET));
                return Base64.getEncoder().encodeToString(signature.sign());
            } catch (Exception e) {
                throw new EncryptionException("RSA2 sign failed!", e);
            }
        }


        /**
         * 公鑰校驗簽名
         * <p>
         * throw {@link InvalidKeySpecException} 無效的 Key Spec
         * throw {@link InvalidKeyException} 無效的 Key
         * throw {@link UnsupportedEncodingException} 不支持的編碼
         * throw {@link SignatureException} 簽名異常
         * throw {@link NoSuchAlgorithmException} 無效的算法
         * throw {@link NoSuchPaddingException} 無效的監間距異常
         *
         * @param content   內容
         * @param sign      簽名
         * @param publicKey 公鑰
         * @return 是否匹配
         */
        public static boolean verify(String content, String sign, String publicKey) {
            try {
                Signature signature = Signature.getInstance(ALGORITHMS_SHA256);
                signature.initVerify(getPublicKey(publicKey));
                signature.update(content.getBytes(DEFAULT_CHARSET));
                return signature.verify(Base64.getDecoder().decode(sign));
            } catch (Exception e) {
                throw new EncryptionException("RSA2 verify failed!", e);
            }
        }

        /**
         * 使用公鑰或者私鑰加密
         * <p>
         * throw {@link IllegalBlockSizeException} 無效塊大小異常
         * throw {@link InvalidKeyException} 無效的 Key
         * throw {@link UnsupportedEncodingException} 不支持的解碼
         * throw {@link BadPaddingException} 錯誤間隔異常
         * throw {@link NoSuchAlgorithmException} 無效的算法
         * throw {@link NoSuchPaddingException} 無效的監間距異常
         *
         * @param content 內容
         * @param key     公鑰或者私鑰
         * @return 密文
         */
        public static String encrypt(String content, Key key) {
            return RSA.encrypt(content, key);
        }

        /**
         * 使用公鑰或者私鑰解密
         * <p>
         * throw {@link IllegalBlockSizeException} 無效塊大小異常
         * throw {@link InvalidKeyException} 無效的 Key
         * throw {@link BadPaddingException} 錯誤間隔異常
         * throw {@link NoSuchAlgorithmException} 無效的算法
         * throw {@link NoSuchPaddingException} 無效的監間距異常
         *
         * @param content 內容
         * @param key     公鑰或者私鑰
         * @return 明文
         */
        public static String decrypt(String content, Key key) {
            return RSA.decrypt(content, key);
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM