【Java 加密算法】常见的五种加密算法案例整理(143)

18 篇文章 0 订阅

直接上代码:

package com.day02;

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.KeySpec;
import java.util.Base64;
import java.util.Formatter;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/*
 * 常见的五种算法加密
 * 
 */

public class EncryptionAlgorithm {
	public static void main(String[] args) throws Exception {
		
		String s1 = "6103211996xxxxxxxx";  // 测试身份证号
        String data1 = md5Encrypt(s1);
        System.out.println("MD5不可逆算法加密的数据:" + data1);
        System.out.println("MD5不可逆算法加密的数据长度::" + data1.length());
        System.out.println("-------------------------------------------------");
        String s2 = "6103211996xxxxxxxx";  // 测试身份证号
        String data2 = SHAEncrypt(s2);
        System.out.println("SHA不可逆算法加密的数据:" + data2);
        System.out.println("SHA512不可逆算法加密的数据长度::" + data2.length());
        System.out.println("-------------------------------------------------");
        String s3 = "6103211996xxxxxxxx";  // 测试身份证号
        String key = "DES12345"; // 密钥,长度必须为8位
        String encryptedData1 = DESEncrypt(s3, key);
        System.out.println("DES对称可逆算法加密后的数据:" + encryptedData1);
        System.out.println("DES对称可逆算法加密后的数据长度::" + encryptedData1.length());
        String decryptedData1 = DESDecrypt(encryptedData1, key);
        System.out.println("DES对称可逆算法解密后的数据:" + decryptedData1);
        System.out.println("-------------------------------------------------");
        String s4 = "6103211996xxxxxxxx";  // 测试身份证号
        String encryptedData2 = AESEncrypt(s4);
        System.out.println("AES对称可逆算法加密后的数据:" + encryptedData2);
        System.out.println("AES对称可逆算法加密后的数据长度:" + encryptedData2.length());
        String decryptedData2 = AESDecrypt(encryptedData2);
        System.out.println("AES对称可逆算法解密后的数据:" + decryptedData2);
        System.out.println("-------------------------------------------------");
        KeyPair keyPair = generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        String s5 = "6103211996xxxxxxxx";  // 测试身份证号
        String encryptedData3 = RSAEncrypt(s5, publicKey);
        System.out.println("RSA非对称可逆算法加密后的数据:" + encryptedData3);
        System.out.println("RSA非对称可逆算法加密后的数据长度:" + encryptedData3.length());
        String decryptedData3 = RSADecrypt(encryptedData3, privateKey);
        System.out.println("RSA非对称可逆算法解密后的数据:" + decryptedData3);
        System.out.println("-------------------------------------------------");

	}
	
	
	/*
	 * 不可逆加密算法一:MD5算法加密(MD5算法的输出长度为128位,通常用32个16进制数表示)
	 * 特点:不可逆(不可逆加密的算法的加密是不可逆的,密文无法被还原成原文),也称为:散列算法;
	 * 优点:计算速度快、输出长度固定、应用广泛等
	 * 缺点:不安全
	 * 
	 */
	private static final String MD5_ALGORITHM = "MD5";
    public static String md5Encrypt(String data) throws Exception {
         // 获取MD5算法实例
         MessageDigest messageDigest = MessageDigest.getInstance(MD5_ALGORITHM);
         // 计算散列值
         byte[] digest = messageDigest.digest(data.getBytes());
         Formatter formatter = new Formatter();
         // 补齐前导0,并格式化
         for (byte b : digest) {
             formatter.format("%02x", b);
         }
         return formatter.toString();
	 }
	    
	 
	 /*
	  * 不可逆加密算法二:SHA-256(SHA系列算法是一组密码散列函数,用于将任意长度的数据映射为固定长度的散列值)
	  * 目前共有SHA-1、SHA-2、SHA-3三种版本。
	  *	SHA-2算法包括SHA-224、SHA-256、SHA-384和SHA-512四种散列函数,分别将任意长度的数据映射为224位、256位、384位和512位的散列值。
	  *	特点:不可逆(不可逆加密的算法的加密是不可逆的,密文无法被还原成原文),但是SHA-2算法安全比MD5强
	  *	散列值长度更长:例如SHA-256算法的散列值长度为256位,而MD5算法的散列值长度为128位,这就提高了攻击者暴力破解或者彩虹表攻击的难度。
	  *	更强的碰撞抗性:SHA算法采用了更复杂的运算过程和更多的轮次,使得攻击者更难以通过预计算或巧合找到碰撞。
	  *	当然,SHA-2也不是绝对安全的,散列算法都有被暴力破解或者彩虹表攻击的风险,所以,在实际的应用中,加盐还是必不可少的。
	  * 
	  */
     private static final String SHA_512_ALGORITHM = "SHA-512";  // SHA-224/SHA-256/SHA-384/SHA-512
     public static String SHAEncrypt(String data) throws Exception {
         //获取SHA-256算法实例
         MessageDigest messageDigest = MessageDigest.getInstance(SHA_512_ALGORITHM);
         //计算散列值
         byte[] digest = messageDigest.digest(data.getBytes());
         StringBuilder stringBuilder = new StringBuilder();
         //将byte数组转换为15进制字符串
         for (byte b : digest) {
             stringBuilder.append(Integer.toHexString((b & 0xFF) | 0x100), 1, 3);
         }
         return stringBuilder.toString();
     }

     
	 /*
	  * 可逆算法加密一:DES(对称加密算法)
	  * 特点:DES算法使用56位密钥对数据进行加密,加密过程中使用了置换、替换、异或等运算,具有较高的安全性
	  *      DES的算法速度较快,但是在安全性上面并不是最优选择,因为DES算法的密钥长度比较短,
	  *      被暴力破解和差分攻击的风险比较高,一般推荐用一些更安全的对称加密算法,比如3DES、AES
	  * 
	  * @param data 待加密的数据
      * @param key  密钥,长度必须为8位
      * @return 加密后的数据,使用Base64编码
	  * 
	  */
     private static final String DES_ALGORITHM = "DES";
     public static String DESEncrypt(String data, String key) throws Exception {
         // 根据密钥生成密钥规范
         KeySpec keySpec = new DESKeySpec(key.getBytes());
         // 根据密钥规范生成密钥工厂
         SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
         // 根据密钥工厂和密钥规范生成密钥
         SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);

         // 根据加密算法获取加密器
         Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
         // 初始化加密器,设置加密模式和密钥
         cipher.init(Cipher.ENCRYPT_MODE, secretKey);
         // 加密数据
         byte[] encryptedData = cipher.doFinal(data.getBytes());
         // 对加密后的数据进行Base64编码
         return Base64.getEncoder().encodeToString(encryptedData);
     }

     /*
      * DES解密
      *
      * @param encryptedData 加密后的数据,使用Base64编码
      * @param key           密钥,长度必须为8位
      * @return 解密后的数据
      */
     public static String DESDecrypt(String encryptedData, String key) throws Exception {
         // 根据密钥生成密钥规范
         KeySpec keySpec = new DESKeySpec(key.getBytes());
         // 根据密钥规范生成密钥工厂
         SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
         // 根据密钥工厂和密钥规范生成密钥
         SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);

         // 对加密后的数据进行Base64解码
         byte[] decodedData = Base64.getDecoder().decode(encryptedData);
         // 根据加密算法获取解密器
         Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
         // 初始化解密器,设置解密模式和密钥
         cipher.init(Cipher.DECRYPT_MODE, secretKey);
         // 解密数据
         byte[] decryptedData = cipher.doFinal(decodedData);
         // 将解密后的数据转换为字符串
         return new String(decryptedData);
     }
 
 
     /*
      * 可逆算法加密二:AES加密(高级加密标准,对称加密算法,AES算法使用的密钥长度为128位、192位或256位,比DES算法的密钥长度更长,安全性更高)
      * 特点:ES算法采用的密钥长度更长,密钥空间更大,安全性更高,能够有效地抵抗暴力破解攻击。
			 当然,因为密钥长度较长,需要的存储也更多。
			 对于对称加密算法而言,最大的痛点就在于密钥管理困难,相比而言,非对称加密就没有这个担忧
      *
      * @param data 待加密的数据
      * @return 加密后的数据,使用Base64编码
      */
     private static final String AES_ALGORITHM = "AES";
     // AES加密模式为CBC,填充方式为PKCS5Padding
     private static final String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding";
     // AES密钥为16位
     private static final String AES_KEY = "1234567890123456";
     // AES初始化向量为16位
     private static final String AES_IV = "abcdefghijklmnop";
     public static String AESEncrypt(String data) throws Exception {
         // 将AES密钥转换为SecretKeySpec对象
         SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(), AES_ALGORITHM);
         // 将AES初始化向量转换为IvParameterSpec对象
         IvParameterSpec ivParameterSpec = new IvParameterSpec(AES_IV.getBytes());
         // 根据加密算法获取加密器
         Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
         // 初始化加密器,设置加密模式、密钥和初始化向量
         cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
         // 加密数据
         byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
         // 对加密后的数据使用Base64编码
         return Base64.getEncoder().encodeToString(encryptedData);
     }

     /*
      * AES解密
      *
      * @param encryptedData 加密后的数据,使用Base64编码
      * @return 解密后的数据
      */
     public static String AESDecrypt(String encryptedData) throws Exception {
         // 将AES密钥转换为SecretKeySpec对象
         SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(), AES_ALGORITHM);
         // 将AES初始化向量转换为IvParameterSpec对象
         IvParameterSpec ivParameterSpec = new IvParameterSpec(AES_IV.getBytes());
         // 根据加密算法获取解密器
         Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
         // 初始化解密器,设置解密模式、密钥和初始化向量
         cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
         // 对加密后的数据使用Base64解码
         byte[] decodedData = Base64.getDecoder().decode(encryptedData);
         // 解密数据
         byte[] decryptedData = cipher.doFinal(decodedData);
         // 返回解密后的数据
         return new String(decryptedData, StandardCharsets.UTF_8);
     }


     /*
      * 可逆加密算法三:RSA(非对称加密算法)
      * 非对称加密算法需要两个密钥,这两个密钥互不相同,但是相互匹配,一个称为公钥,另一个称为私钥。
	  *	使用其中的一个加密,则使用另一个进行解密。例如使用公钥加密,则需要使用私钥解密。
	  *	特点:RSA算法的优点是安全性高,公钥可以公开,私钥必须保密,保证了数据的安全性;可用于数字签名、密钥协商等多种应用场景。
	  *		 缺点是加密、解密速度较慢,密钥长度越长,加密、解密时间越长;密钥长度过短容易被暴力破解,密钥长度过长则会增加计算量和存储空间的开销。
	  *
      * 生成RSA密钥对
      *
      * @return RSA密钥对
      */
     private static final String RSA_ALGORITHM = "RSA";
     public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
         KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
         keyPairGenerator.initialize(2048); // 密钥大小为2048位
         return keyPairGenerator.generateKeyPair();
     }

     /*
      * 使用公钥加密数据
      *
      * @param data      待加密的数据
      * @param publicKey 公钥
      * @return 加密后的数据
      */
     public static String RSAEncrypt(String data, PublicKey publicKey) throws Exception {
         Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
         cipher.init(Cipher.ENCRYPT_MODE, publicKey);
         byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
         return Base64.getEncoder().encodeToString(encryptedData);
     }

     /*
      * 使用私钥解密数据
      *
      * @param encryptedData 加密后的数据
      * @param privateKey    私钥
      * @return 解密后的数据
      */
     public static String RSADecrypt(String encryptedData, PrivateKey privateKey) throws Exception {
         byte[] decodedData = Base64.getDecoder().decode(encryptedData);
         Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
         cipher.init(Cipher.DECRYPT_MODE, privateKey);
         byte[] decryptedData = cipher.doFinal(decodedData);
         return new String(decryptedData, StandardCharsets.UTF_8);
     }

}

测试输出:

MD5不可逆算法加密的数据:9ac85b1b9b3aa99bf769ffd9d5eeaabc
MD5不可逆算法加密的数据长度::32
-------------------------------------------------
SHA不可逆算法加密的数据:ab4b60c37f52de81ce28d55604efc42b08e803db25928f1d7ee428bec1b16c57e787a1df4ee438e13a625936e6d591903dd320f04b3e5b6468b039b82ff799b5
SHA512不可逆算法加密的数据长度::128
-------------------------------------------------
DES对称可逆算法加密后的数据:BNMgizZYKuxP+tDUJlZCAcTAxPQj3jjH
DES对称可逆算法加密后的数据长度::32
DES对称可逆算法解密后的数据:6103211996xxxxxxxx
-------------------------------------------------
AES对称可逆算法加密后的数据:cmgyllaA6AAYJBHNS4WMvwd12HhnCzQw9lvrlkP51M8=
AES对称可逆算法加密后的数据长度:44
AES对称可逆算法解密后的数据:6103211996xxxxxxxx
-------------------------------------------------
RSA非对称可逆算法加密后的数据:shrFh9f6DDbtsY0sdIYWqHiAlMn51anoI1COJj6PyLPDOhP0VXduLOsjqCSA9o45DukvpgQg6N2cSQIsPYHr4GXfSIrMNePk4mlzXPD3UZkHZrhY7rzQND/t7kpfyWUCjmgaOBA+5QstD5toIA8RQF27HKiQWOOAaNL42wVGA5KUtGth5gKhyOtFmo+wrdgZ3LHEny8xq4xMEISVc8J/O0n+z6RWbJxQ3Qrn2qWFM2zd4Ui8PHaeRKq1rPfbmn5DJZDWDwUmqpWqWbF8jwtW6XMcz9EqLjqVrgKbsu0/69Ww9mz1bJ1UtqgdACv1Zp032KMaHhtXxeaTfSvZpEJeZw==
RSA非对称可逆算法加密后的数据长度:344
RSA非对称可逆算法解密后的数据:6103211996xxxxxxxx
-------------------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KevinDuc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值