java 对称加密

开发过程中经常会用到对称加密,下面简单说一下,有哪些经常使用的对称加密算法

一:DES

public class DESUtil {
	private static final String KEY_ALGORITHM = "DES";
	private static final String DEFAULT_CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";// 默认的加密算法

	/**
	 * DES 加密操作
	 * 
	 * @return 返回Base64转码后的加密数据
	 */
	public static String encrypt(String content, String key) {
		try {
			Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器

			byte[] byteContent = content.getBytes("utf-8");

			cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));// 初始化为加密模式的密码器

			byte[] result = cipher.doFinal(byteContent);// 加密

			return Base64.getEncoder().encodeToString(result);// 通过Base64转码返回
		} catch (Exception ex) {
			Logger.getLogger(DESUtil.class.getName()).log(Level.SEVERE, null, ex);
		}

		return null;
	}

	/**
	 * DES 解密操作
	 */
	public static String decrypt(String content, String key) {

		try {
			// 实例化
			Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

			// 使用密钥初始化,设置为解密模式
			cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));

			// 执行操作
			byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));

			return new String(result, "utf-8");
		} catch (Exception ex) {
			Logger.getLogger(DESUtil.class.getName()).log(Level.SEVERE, null, ex);
		}

		return null;
	}

	/**
	 * 生成加密秘钥
	 *
	 * @return
	 */
	private static SecretKeySpec getSecretKey(final String key) {
		// 返回生成指定算法密钥生成器的 KeyGenerator 对象
		KeyGenerator kg = null;

		try {
			kg = KeyGenerator.getInstance(KEY_ALGORITHM);

			// DES 要求密钥长度为 56
			kg.init(56, new SecureRandom(key.getBytes()));

			// 生成一个密钥
			SecretKey secretKey = kg.generateKey();

			return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为DES专用密钥
		} catch (NoSuchAlgorithmException ex) {
			Logger.getLogger(DESUtil.class.getName()).log(Level.SEVERE, null, ex);
		}

		return null;
	}

	public static void main(String[] args) {
		String content = "hello,您好,李四,我喜欢你,这个内容加密了,别人不知道的";
		String key = "sde@5f98H*^hsff%dfs$r344&df8543*er";
		System.out.println("原始内容:" + content);
		String s1 = DESUtil.encrypt(content, key);
		System.out.println("加密后:" + s1);
		System.out.println("解密后:" + DESUtil.decrypt(s1, key));
	}
}

二:3DES

/**
 * 对称加密 【3DES】
 * 
 * @author it
 */
public class TripDESUtil {
	private static final String KEY_ALGORITHM = "DESede";
	private static final String DEFAULT_CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding";// 默认的加密算法

	/**
	 * DESede 加密操作
	 * 
	 * @return 返回Base64转码后的加密数据
	 */
	public static String encrypt(String content, String key) {
		try {
			Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器

			byte[] byteContent = content.getBytes("utf-8");

			cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));// 初始化为加密模式的密码器

			byte[] result = cipher.doFinal(byteContent);// 加密

			return Base64.getEncoder().encodeToString(result);// 通过Base64转码返回
		} catch (Exception ex) {
			Logger.getLogger(TripDESUtil.class.getName()).log(Level.SEVERE, null, ex);
		}

		return null;
	}

	/**
	 * DESede 解密操作
	 */
	public static String decrypt(String content, String key) {

		try {
			// 实例化
			Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

			// 使用密钥初始化,设置为解密模式
			cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));

			// 执行操作
			byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));

			return new String(result, "utf-8");
		} catch (Exception ex) {
			Logger.getLogger(TripDESUtil.class.getName()).log(Level.SEVERE, null, ex);
		}

		return null;
	}

	/**
	 * 生成加密秘钥
	 */
	private static SecretKeySpec getSecretKey(final String key) {
		// 返回生成指定算法密钥生成器的 KeyGenerator 对象
		KeyGenerator kg = null;

		try {
			kg = KeyGenerator.getInstance(KEY_ALGORITHM);

			// DESede
			kg.init(new SecureRandom(key.getBytes()));

			// 生成一个密钥
			SecretKey secretKey = kg.generateKey();

			return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为DESede专用密钥
		} catch (NoSuchAlgorithmException ex) {
			Logger.getLogger(TripDESUtil.class.getName()).log(Level.SEVERE, null, ex);
		}

		return null;
	}

	public static void main(String[] args) {
		String content = "hello,您好,李四,我喜欢你,这个内容加密了,别人不知道的";
		String key = "sde@5f98H*^hsff%dfs$r344&df8543*er";
		System.out.println("原始内容:" + content);
		String s1 = TripDESUtil.encrypt(content, key);
		System.out.println("加密后:" + s1);
		System.out.println("解密后:" + TripDESUtil.decrypt(s1, key));
	}
}

三:AES

AES三个基本的概念:密钥、填充、模式。

1、秘钥:

AES支持三种长度的秘钥,128位,192位,256位,平时大家所说的AES128,AES192,AES256,实际上就是指的AES算法对不同长度密钥的使用。从安全性能上来说,AES256安全性最高。从性能来看,AES128性能最高。本质原因是它们的加密处理轮数不同

2、填充:

AES算法在对明文加密的时候,并不是把整个明文一股脑加密成一整段密文,而是把明文拆分成一个个独立的明文块,每一个明文块长度128bit。这些明文块经过AES加密器的复杂处理,生成一个个独立的密文块,这些密文块拼接在一起,就是最终的AES加密结果。

假如一段明文长度是192bit,如果按每128bit一个明文块来拆分的话,第二个明文块只有64bit,不足128bit。这时候怎么办呢?就需要对明文块进行填充(Padding)。

填充方式:

  • @1:NoPadding
    • 不做任何填充,但是要求明文必须是16字节的整数倍。
  • @2:SO10126Padding
    • 如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字节,最后一个字符值等于缺少的字符数,其他字符填充随机数,比如明文:{1,2,3,4,5,a,b,c,d,e},缺少6个字节,则可能补全为{1,2,3,4,5,a,b,c,d,e,5,c,3,G,$,6}
  • @3:PKCS5Padding
    • 如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字符,且每个字节的值等于缺少的字符数。比如明文:{1,2,3,4,5,a,b,c,d,e},缺少6个字节,则补全为{1,2,3,4,5,a,b,c,d,e,6,6,6,6,6,6}

3、模式:

AES的工作模式,体现在把明文块加密成密文块的处理过程中。AES加密算法提供了五种不同的工作模式:ECB、CBC、CTR、CFB、OFB

AES工作 模式模式的基本定义
ECB模式(默认)电码本模式 Electronic Codebook Book
CBC模式:密码分组链接模式 CipherBlock Chaining
CTR模式:计算器模式 Counter
CFB模式:密码反馈模式 CipherFeedBack
OFB模式:输出反馈模式 OutputFeedBack

四:AES 代码示例

public class AESUtil {
	private static final String KEY_ALGORITHM = "AES";
	private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";// 默认的加密算法

	/**
	 * AES 加密操作
	 * 
	 * @return 返回Base64转码后的加密数据
	 */
	public static String encrypt(String content, String key) {
		try {
			Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器

			byte[] byteContent = content.getBytes("utf-8");

			cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));// 初始化为加密模式的密码器

			byte[] result = cipher.doFinal(byteContent);// 加密

			return Base64.getEncoder().encodeToString(result);// 通过Base64转码返回
		} catch (Exception ex) {
			Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
		}

		return null;
	}

	/**
	 * AES 解密操作
	 */
	public static String decrypt(String content, String key) {

		try {
			// 实例化
			Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

			// 使用密钥初始化,设置为解密模式
			cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));

			// 执行操作
			byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));

			return new String(result, "utf-8");
		} catch (Exception ex) {
			Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
		}

		return null;
	}

	/**
	 * 生成加密秘钥
	 */
	private static SecretKeySpec getSecretKey(final String key) {
		// 返回生成指定算法密钥生成器的 KeyGenerator 对象
		KeyGenerator kg = null;

		try {
			kg = KeyGenerator.getInstance(KEY_ALGORITHM);

			// AES 要求密钥长度为 128
			kg.init(128, new SecureRandom(key.getBytes()));

			// 生成一个密钥
			SecretKey secretKey = kg.generateKey();

			return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
		} catch (NoSuchAlgorithmException ex) {
			Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
		}

		return null;
	}

	public static void main(String[] args) {
		String content = "hello,您好,李四,我喜欢你,这个内容加密了,别人不知道的";
		String key = "sde@5f98H*^hsff%dfs$r344&df8543*er";
		System.out.println("原始内容:" + content);
		String s1 = AESUtil.encrypt(content, key);
		System.out.println("加密后:" + s1);
		System.out.println("解密后:" + AESUtil.decrypt(s1, key));
	}
}

另一种方法

    //AES-128-cbc KEY 需要为16位
    private static final String sKey="XXXXXXXXXXXXXXX";
    private static final String ivParameter="YYYYYYYYYYYYYYYY";//iv 偏移量


   			int pwdLength=word.length();
            int count=(4-pwdLength%4)%4;
            for(int i=0;i<count;i++){
                word=word+"=";
            }
            word.replaceAll("-","+").replaceAll("_","/");
            byte[] raw=sKey.getBytes("utf-8");
 			SecretKeySpec skeySpec=new  SecretKeySpec(raw,"AES");
            Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv=new IvParameterSpec(ivParameter.getBytes());
            cipher.init(Cipher.DECRYPT_MODE,skeySpec,iv);
            byte[] encrypted1=Base64.getDecoder().decode(word);//base64解密
            byte[] original1=cipher.doFinal(encrypted1);
            String originalString=new String(original1);
            return originalString;

ref:https://blog.csdn.net/dengjili/article/details/85862201

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值