3DES加密为对称加密算法,在Java实现中3DES的默认加密方式为ECB,默认填充方式为PKCS5Padding。密钥由服务方提供给客户方,即加解密都使用同一个密钥,所以只要有一方暴露了密钥就会存在安全问题。

       RSA为非对称加密,需要有一对密钥,分别为公钥和私钥。如果使用者加解密过程,使用私钥加密,公钥解密;或者使用公钥加密,私钥解密。如果使用在签名和验签过程,则使用私钥签名,公钥验签;或者公钥签名,私钥验签。这样保证了只有一方暴露了密钥,不会产生安全威胁。

  3DES加解密、DES加解密与RSA签名验签的Java实现:

public class EncryptUtil {

    private static final String CHAR_SET_UTF8 = "UTF-8";
    private static final String ALGORITHM_3DES = "DESede";
    private static final String ALGORITHM_3DES_PADDING = "DESede/ECB/PKCS5Padding";
    private static final String ALGORITHM_DES = "DES";
    private static final String ALGORITHM_MD5_WITH_RSA = "MD5withRSA";
    private static final String ALGORITHM_RSA = "RSA";

    /**
     * 3DES加密
     *
     * @param content 加密内容
     * @param key     密钥
     * @return
     */
    public static String tripleDESEncrypt(String content, byte[] key) {
        try {
            // 根据key转换为对应的SecretKey对象
            DESedeKeySpec spec = new DESedeKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_3DES);
            SecretKey tripleDesKey = keyFactory.generateSecret(spec);
            // 初始化为加密模式的密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM_3DES_PADDING);
            cipher.init(Cipher.ENCRYPT_MODE, tripleDesKey);
            // 加密
            byte[] result = cipher.doFinal(content.getBytes(CHAR_SET_UTF8));
            // 通过Base64转码返回
            return Base64.encodeBase64String(result);
        } catch (Exception e) {
            log.error("3DES加密失败!", e);
            throw new BusinessException("3DES加密失败!", e);
        }
    }

    /**
     * 3DES解密
     *
     * @param content 解密内容
     * @param key     密钥
     * @return
     */
    public static String tripleDESDecrypt(byte[] content, byte[] key) {
        try {
            // 根据key转换为对应的SecretKey对象
            DESedeKeySpec spec = new DESedeKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_3DES);
            SecretKey tripleDesKey = keyFactory.generateSecret(spec);
            // 实例化 使用密钥初始化,设置为解密模式
            Cipher cipher = Cipher.getInstance(ALGORITHM_3DES_PADDING);
            // 执行操作
            cipher.init(Cipher.DECRYPT_MODE, tripleDesKey);
            byte[] result = cipher.doFinal(content);
            return new String(result);
        } catch (Exception e) {
            log.error("3DES解密失败额!", e);
            throw new BusinessException("3DES解密失败!", e);
        }
    }

    /**
     * DES加密
     *
     * @param byteContent 加密内容
     * @param key     密钥
     * @return
     */
    public static byte[] desEncrypt(byte[] byteContent, byte[] key) {
        try {
            // 根据key转换为对应的SecretKey对象
            DESKeySpec desKeySpec = new DESKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_DES);
            SecretKey desKey = keyFactory.generateSecret(desKeySpec);
            // 初始化为加密模式的密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
            cipher.init(Cipher.ENCRYPT_MODE, desKey);

            // 加密
            byte[] result = cipher.doFinal(byteContent);
            return result;
        } catch (Exception e) {
            log.error("3DES加密失败!", e);
            throw new BusinessException("3DES加密失败!", e);
        }
    }

    /**
     * DES解密
     *
     * @param byteContent 加密内容
     * @param key     密钥
     * @return
     */
    public static byte[] desDecrypt(byte[] byteContent, byte[] key) {
        try {
            // 根据key转换为对应的SecretKey对象
            DESKeySpec desKeySpec = new DESKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_DES);
            SecretKey desKey = keyFactory.generateSecret(desKeySpec);
            // 初始化为加密模式的密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
            cipher.init(Cipher.DECRYPT_MODE, desKey);
            // 解密
            byte[] result = cipher.doFinal(byteContent);
            return result;
        } catch (Exception e) {
            log.error("des解密失败!", e);
            throw new BusinessException("des解密失败!", e);
        }
    }

    /**
     * 生成MD5WithRSA数字签名
     *
     * @param content    需要发送的报文内容
     * @param privateKey 私钥
     * @return
     * @throws Exception
     */
    public static String generateMD5WithRSASign(String content, String privateKey) {
        try {
            // 生成私钥对象
            KeyFactory factory = KeyFactory.getInstance(ALGORITHM_RSA);
            byte[] keyBytes2 = Base64.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes2);
            PrivateKey key = factory.generatePrivate(pkcs8EncodedKeySpec);
            byte[] contentBytes = content.getBytes(CHAR_SET_UTF8);
            // 返回MD5withRSA签名算法的 Signature对象
            Signature signature = Signature.getInstance(ALGORITHM_MD5_WITH_RSA);
            signature.initSign(key);
            signature.update(contentBytes);
            byte[] signs = signature.sign();
            return Base64.encodeBase64String(signs);
        } catch (Exception e) {
            log.error("生成数字签名异常!", e);
            throw new BusinessException("生成数字签名异常!", e);
        }
    }

    /**
     * 验证MD5WithRSA数字签名
     *
     * @param content   接收到的报文内容
     * @param sign      接收到的数字签名
     * @param publicKey 公钥
     * @return
     * @throws Exception
     */
    public static boolean verifyMD5WithRSASign(String content, byte[] sign, String publicKey) {
        try {
            // 生成公钥对象
            byte[] keyBytes = Base64.decodeBase64(publicKey);
            KeyFactory factory = KeyFactory.getInstance(ALGORITHM_RSA);
            X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
            PublicKey pubKey = factory.generatePublic(spec);

            // 对用md5和RSA私钥生成的数字签名进行验证
            byte[] contentBytes = content.getBytes(CHAR_SET_UTF8);
            Signature signature = Signature.getInstance(ALGORITHM_MD5_WITH_RSA);
            signature.initVerify(pubKey);
            signature.update(contentBytes);
            return signature.verify(sign);
        } catch (Exception e) {
            log.error("验证数字签名异常!", e);
            throw new BusinessException("验证数字签名异常!", e);
        }
    }

    /**
     * 生成文件MD5摘要
     *
     * @param file 文件
     * @return
     */
    public String generateFileMD5(File file) {
        FileInputStream inputStream = null;
        String md5Message = null;
        try {
            inputStream = new FileInputStream(file);
            md5Message = DigestUtils.md5Hex(inputStream);
            return md5Message;
        } catch (Exception e) {
            log.error("文件MD5异常!", e);
            throw new BusinessException("文件MD5异常!", e);
        }

    }

    /**
     * 生成密钥对,生成过后如果没有特殊情况不需要重新申请
     *
     * @return
     * @throws Exception
     */
    public static Map<String,String> generateKeyPair() {
        KeyPairGenerator keyGen = null;
        Map<String,String> keyMap = new HashMap<>();
        try {
            keyGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
            // 秘钥长度
            keyGen.initialize(1024);
            KeyPair keyPair = keyGen.generateKeyPair();
            PrivateKey aPrivate = keyPair.getPrivate();
            String privateKey = Base64.encodeBase64String(aPrivate.getEncoded());
            PublicKey aPublic = keyPair.getPublic();
            String publicKey = Base64.encodeBase64String(aPublic.getEncoded());
            keyMap.put("privateKey",privateKey);
            keyMap.put("publicKey",publicKey);
            return keyMap;
        } catch (NoSuchAlgorithmException e) {
            throw new BusinessException("生成密钥对异常!", e);
        }
    }
}

 

探索不以困难而止,学习不以艰苦而终