Java实现AES加解密

1 篇文章 0 订阅

一、关于AES和其它几个加密方式的了解:

       AES/DES加密速度快,适合大量数据,DES容易破解,一般用3重DES,后来又出现了更快更安全的AES,RSA是公钥加密,速度慢,只能处理少量数据,优点是公钥即使在不安全的网络上公开,也能保证安全,常见情况是双方用RSA协商出一个密钥后通过AES/3DES给数据加密。

二、用java处理的AES加密和解密方式

1.上代码

package com.yinxin.ceshi;

import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class TestAES {
	Cipher ecipher;
	Cipher dcipher;

	/**
	 * Input a string that will be md5 hashed to create the key.
	 * 
	 * @return void, cipher initialized
	 */
	public TestAES() {
		try {
			SecretKeySpec skey = new SecretKeySpec(
					"9f265d42ab3c66d8f50a3a2e793a30c2".getBytes(), "AES");
			this.setupCrypto(skey);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public TestAES(String key) {
		SecretKeySpec skey = new SecretKeySpec(getMD5(key), "AES");
		this.setupCrypto(skey);
	}

	private void setupCrypto(SecretKey key) {
		// Create an 8-byte initialization vector
		byte[] iv = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

		AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
		try {
			ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

			// CBC requires an initialization vector
			ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
			dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/***
	 * AES加密
	 * 
	 * @param in
	 * @param out
	 */
	public void encrypt(InputStream in, OutputStream out) {
		byte[] buf = new byte[1024];
		try {
			// Bytes written to out will be encrypted
			out = new CipherOutputStream(out, ecipher);

			// Read in the cleartext bytes and write to out to encrypt
			int numRead = 0;
			while ((numRead = in.read(buf)) >= 0) {
				out.write(buf, 0, numRead);
			}
			out.close();
		} catch (java.io.IOException e) {
			e.printStackTrace();
		}
	}

	/***
	 * AES加密
	 * 
	 * @param plaintext
	 */
	public String encrypt(String plaintext) {
		try {
			byte[] ciphertext = ecipher.doFinal(plaintext.getBytes("UTF-8"));
			return byteToHex(ciphertext);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

	}

	/***
	 * AES解密
	 * 
	 * @param in
	 * @param out
	 */
	public void decrypt(InputStream in, OutputStream out) {
		try {
			byte[] buf = new byte[1024];
			// Bytes read from in will be decrypted
			in = new CipherInputStream(in, dcipher);

			// Read in the decrypted bytes and write the cleartext to out
			int numRead = 0;
			while ((numRead = in.read(buf)) >= 0) {
				out.write(buf, 0, numRead);
			}
			out.close();
		} catch (java.io.IOException e) {
			e.printStackTrace();
		}
	}

	/***
	 * AES解密
	 * 
	 * @param hexCipherText
	 */
	public String decrypt(String hexCipherText) {
		try {
			String plaintext = new String(
					dcipher.doFinal(hexToByte(hexCipherText)), "UTF-8");
			return plaintext;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/***
	 * AES解密
	 * 
	 * @param ciphertext
	 */
	public String decrypt(byte[] ciphertext) {
		try {
			String plaintext = new String(dcipher.doFinal(ciphertext), "UTF-8");
			return plaintext;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private static byte[] getMD5(String input) {
		try {
			byte[] bytesOfMessage = input.getBytes("UTF-8");
			MessageDigest md = MessageDigest.getInstance("MD5");
			return md.digest(bytesOfMessage);
		} catch (Exception e) {
			return null;
		}
	}

	static final String HEXES = "0123456789ABCDEF";

	/***
	 * byte[]转16进制字符串
	 * 
	 * @param raw
	 * @return
	 */
	public static String byteToHex(byte[] raw) {
		if (raw == null) {
			return null;
		}
		final StringBuilder hex = new StringBuilder(2 * raw.length);
		for (final byte b : raw) {
			hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(
					HEXES.charAt((b & 0x0F)));
		}
		return hex.toString();
	}

	/***
	 * 16进制字符串转byte[]
	 * 
	 * @param raw
	 * @return
	 */
	public static byte[] hexToByte(String hexString) {
		int len = hexString.length();
		byte[] ba = new byte[len / 2];
		for (int i = 0; i < len; i += 2) {
			ba[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
					.digit(hexString.charAt(i + 1), 16));
		}
		return ba;
	}

	public static void main(String[] args) {
		String str="SHIYUNPENG";
	}

}

2.测试检查加解密

附上测试代码:

public static void main(String[] args) {
		String str="把孤独当作晚餐却难以下咽    把黑夜当作是温暖却难以入眠"
				+ "只好对自己说晚安   无人在身边"
				+ "想要遗忘却不心甘   把难过当作幻念都烟消云散"
				+ "把感情当作红线全部都斩断    这时间好像都放慢"
				+ "像度日如年    想要遗忘我还是不甘";
		String MY="sdgs@#12ad##@2423sdf@$*((*)ghgs23846gsjgs&%$%#gsjfg%6646fhfhU52364926423648326jsfjbsdj%^%#$^%GHFJV";  //双方协商好的密钥
		String aesStr=new TestAES(MY).encrypt(str);
		System.out.println("AES加密后的字符串为:\n["+aesStr+"]\n");
		//进行解密后的内容:
		String de=new TestAES(MY).decrypt(aesStr);
		System.out.println("AES解密后的内容为:\n["+de+"]");
	}

测试效果图:

 控制台打印字符串:

AES加密后的字符串为:
[004C9C14ADE1533AD379954BDBEA2041F6B2414B394ED045DE11584994D6D4691A59643CF540B429E8E349A1E14C7B80CF65351B9A61CBEED87315F3A016212DF1D7F38C266C7DD1A07C10F346043B6000EBEE2AB5159E7AAE91BE82C800C246D914C7B854FB3142D26594861F33A6C217C635FB4DEA99E565486430CD0A8A4958C1ABD79078B5D533DFC79E640DF4DFC3AA88796DC76B0A8B37B35FD5696DBA091E07158A18CB0AA7B0E7A97DAEF0428AF982FF272B2584A25764AF2169C95E31FF220F6B2DD0081D78F927E273FCEA830E898D775EE0A9DA20A429F8E46980D037ABF9277923EC86F91E8F5872CFF7E7AC70D0EFAD4B53B8491A955D48E31AE08F1EE0DB116C23975E4A6B5B94B8BF7C7DB26FBDC4AEFFF6057B9896F690BFDA00956882B6D302FED3C12CBE15ABF8]

AES解密后的内容为:
[把孤独当作晚餐却难以下咽    把黑夜当作是温暖却难以入眠只好对自己说晚安   无人在身边想要遗忘却不心甘   把难过当作幻念都烟消云散把感情当作红线全部都斩断    这时间好像都放慢像度日如年    想要遗忘我还是不甘]

注:

    如果你要对文件进行加密,都一样,肯定也是先拿到文件,然后读取里面的内容,再进行加密啊,然后再把加密内容写入另一个文件,就搞定了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是Java实现AES加解密的示例代码: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class AESUtil { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String CHARSET = "UTF-8"; /** * AES加密 * * @param data 待加密的数据 * @param key 密钥 * @param iv 向量 * @return 加密后的数据 * @throws Exception */ public static String encrypt(String data, String key, String iv) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(CHARSET), "AES"); IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(CHARSET)); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec); byte[] encrypted = cipher.doFinal(data.getBytes(CHARSET)); return Base64.getEncoder().encodeToString(encrypted); } /** * AES解密 * * @param data 待解密的数据 * @param key 密钥 * @param iv 向量 * @return 解密后的数据 * @throws Exception */ public static String decrypt(String data, String key, String iv) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(CHARSET), "AES"); IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(CHARSET)); cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec); byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(data)); return new String(decrypted, CHARSET); } } ``` 使用示例: ```java public class Test { public static void main(String[] args) throws Exception { String data = "Hello, world!"; String key = "0123456789abcdef"; String iv = "0123456789abcdef"; String encrypted = AESUtil.encrypt(data, key, iv); String decrypted = AESUtil.decrypt(encrypted, key, iv); System.out.println("加密前的数据:" + data); System.out.println("加密后的数据:" + encrypted); System.out.println("解密后的数据:" + decrypted); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

醉梦洛

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

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

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

打赏作者

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

抵扣说明:

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

余额充值