对称加密算法

本文介绍了对称加密算法中的AES加密,重点讲解了AES的ECB和CBC两种工作模式。ECB模式简单但安全性较低,而CBC模式通过随机的初始化向量提高安全性。示例代码展示了如何在Java中使用AES进行加密和解密操作,包括密钥生成、加密解密流程,以及密文与IV的组合与分离。
摘要由CSDN通过智能技术生成

对称加密

概述:对称加密算法就是传统的用一个密码加密和解密,在软件开发中,常用的对称加密算法有:

算法密钥长度工作模式填充模式
DES56/64ECB/CBC/PCBC/...NopPadding/PKCS5Padding/...
AES128/192/256ECB/CBC/PCBC/...NopPadding/PKCS5Padding//PKCS7Padding/...
IDEA128ECBPKCS5Padding//PKCS7Padding/...

密钥的长度直接决定加密强度,而工作模式和填充模式可以看成是对对称加密算法的参数和格式选择。Java标准库提供的算法实现并不包括所有的工作模式和填充模式。但是我们通常只需要挑选常用的使用就可以了 。DES算法由于密钥过短,可以在短时间内暴力破解,所以现在已经不安全了。

使用AES加密

AES算法是目前应用最广泛的加密算法,比较常见的工作模式是ECB和CBC。

ECB模式:

package com.impudent.Test03;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class Demo02 {
	public static void main(String[] args) throws Exception {
		//原文
		String message="Hello,World!";
		System.out.println("Message: "+message);
		
		//128位密钥=16 bytes key 
		byte[] key="1234567890abcdef".getBytes();
		
		//加密
		byte[] data=message.getBytes();
		byte[] encrypted=encrypt(key, data);
		System.out.println("Encrypted(加密)"+Base64.getEncoder().encodeToString(encrypted));
		
		//解密
		byte[] decrypted=decrypt(key, encrypted);
		System.out.println("Decrypted(解密)"+new String(decrypted));
		
	}
	//加密
	public static byte[] encrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException  {
		//创建密码对象,需要传入算法/工具模式/填充模式
		Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
		
		//根据key的字节内容,“恢复”密钥对象
		SecretKey Keyspec=new SecretKeySpec(key, "AES");
		
		//初始化密钥:设置加密模式ENCRYPT_MODE
		cipher.init(Cipher.ENCRYPT_MODE, Keyspec);
		
		//根据原始内容进行加密
		return cipher.doFinal(input);
		
	}
	//解密
	public static byte[] decrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException  {
		//创建密码对象,需要传入算法/工具模式/填充模式
		Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
		
		//根据key字节内容,“恢复”密钥对象
		SecretKey keyspec=new SecretKeySpec(key, "AES");
		
		//初始化密钥:设置解密模式DECRYPT_MODE
		cipher.init(Cipher.DECRYPT_MODE, keyspec);
		
		//根据原始内容进行解密
		return cipher.doFinal(input);
	}
}

 

CBC模式:ECB模式是最简单的AES加密模式,它只需要一个固定长度的密钥,固定的明文会生成固定的密文,这种一对一的加密模式会导致安全性降低,更好的方式是通过CBC模式,它需要一个随机数作为IV参数,这样对于同一份明文,每次产生的密文都不同。

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Demo03 {
	public static void main(String[] args) throws Exception {
		//原文
		String message="Hello,World!";
		System.out.println("Message: "+message);
		
		//128位密钥=16 bytes key 
		byte[] key="1234567890abcdef1234567890abcdef".getBytes();
		
		//加密
		byte[] data=message.getBytes();
		byte[] encrypted=encrypt(key, data);
		System.out.println("Encrypted(加密)"+Base64.getEncoder().encodeToString(encrypted));
		
		//解密
		byte[] decrypted=decrypt(key, encrypted);
		System.out.println("Decrypted(解密)"+new String(decrypted));
		
	}
	//加密
	public static byte[] encrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException  {
		//创建密码对象,需要传入算法/工具模式/填充模式
		Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
		
		//根据key的字节内容,“恢复”密钥对象
		SecretKey Keyspec=new SecretKeySpec(key, "AES");
		
		//CBC模式需要生成一个16 bytes的initialization vector
		SecureRandom sr=SecureRandom.getInstanceStrong();
		byte[] iv=sr.generateSeed(16);
		System.out.println(Arrays.toString(iv));
		IvParameterSpec ivps=new IvParameterSpec(iv);
		
		//初始化密钥:设置加密模式ENCRYPT_MODE
		cipher.init(Cipher.ENCRYPT_MODE, Keyspec,ivps);
		
		//加密
		byte[] data= cipher.doFinal(input);
		
		//IV不需要保密,把IV和密文一起返回
		return join(iv,data);
		
	}
	//解密
	public static byte[] decrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException  {
		//把input分割为IV和密文
		byte[] iv=new byte[16];
		byte[] data=new byte[input.length-16];
		
		System.arraycopy(input, 0, iv, 0, 16);
		System.arraycopy(input, 16, data, 0, data.length);
		System.out.println(Arrays.toString(iv));
				
		//解密
		Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
		SecretKey keyspec=new SecretKeySpec(key, "AES");
		IvParameterSpec ivps=new IvParameterSpec(iv);
				
		//初始化密钥:操作模式、密钥、IV参数
		cipher.init(Cipher.DECRYPT_MODE, keyspec,ivps);
		
		//解密操作
		return cipher.doFinal(data);
	}
	public static byte[] join(byte[] bs1,byte[] bs2) {
		byte[] r=new byte[bs1.length+bs2.length];
		System.arraycopy(bs1, 0, r, 0, bs1.length);
		System.arraycopy(bs2, 0, r, bs1.length, bs2.length);
		return r;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值