Java AES实现对称加密

前言:

AES:高级加密标准(英语:Advanced Encryption Standard,缩写:AES),这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用,AES的优势之一是至今尚未被破解。AES通常用于移动通信系统加密以及基于SSH协议的软件。

 

测试:

import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
import org.junit.Test;

public class testAES {

	@Test
	public void AES() {
		try {
			String middleKey = "123456";  //就是所谓的密钥,加密和解密双方都需要
			String password = "kevin";    //需要被加密的内容
			
			// 生成KEY
			KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
			keyGenerator.init(new SecureRandom(middleKey.getBytes()));
			SecretKey secretKey = keyGenerator.generateKey();
			byte[] byteKey = secretKey.getEncoded();
			Key key = new SecretKeySpec(byteKey, "AES");
			

			// 加密
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] result = cipher.doFinal(password.getBytes());
			System.out.println("加密后:" + Hex.encodeHexString(result));

			// 解密
			cipher.init(Cipher.DECRYPT_MODE, key);
			result = cipher.doFinal(result);
			System.out.println("解密后:" + new String(result));

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行结果如下: 

 Java AES实现对称加密_第1张图片

 

编写工具类:

AesUtils:

import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

public class AesUtils {
	private final String MiddleKey = "123456";//生成key需要的密码

	public String encrypt(String password) {
		try {
			// 加密
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, getKey());
			byte[] result = cipher.doFinal(password.getBytes());
			// return Hex.encodeHexString(result); 
			return Base64.encodeBase64String(result);//通过Base64转码返回
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
    
	/*
     * encryptedPassword:待解密的密文
     */
	public String decrypt(String encryptedPassword) {
		try {
			// 解密
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.DECRYPT_MODE, getKey());
			// byte[] result = cipher.doFinal(encryptedPassword.getBytes());
			byte[] result = cipher.doFinal(Base64.decodeBase64(encryptedPassword));
			return new String(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

	private Key key;

	public Key getKey() {
		if (key == null) {
			try {
				// 生成KEY ,AES 要求密钥长度为 128
				KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
				SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
		            secureRandom.setSeed(MiddleKey.getBytes());
				keyGenerator.init(128,secureRandom);
				SecretKey secretKey = keyGenerator.generateKey();
				byte[] byteKey = secretKey.getEncoded();

				// 转换KEY
				key = new SecretKeySpec(byteKey, "AES");
				return key;
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		} else {
			return key;
		}
	}
}

使用:

	public void main() {
		AesUtils aesUtils=new AesUtils();
		String encryptStr = aesUtils.encrypt("hello world");
		System.out.println("加密后的结果:"+ encryptStr);
		
		String decryptStr = aesUtils.decrypt(encryptStr);
		System.out.println("解密后的结果:"+ decryptStr);
	}

运行结果如下: 

 

问题: 

1.AesUtils中加密和加密函数中分别有一句被注释的代码,然后改成了base64转码,这是因为使用注释的代码在解密的时候会报错:

javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.   at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991)

原因是直接用tostring 和getbytes方法操作 加密后的byte [ ] 会丢失信息

解决方案就是:
要么使用Base64来转码   
要么像上方Test方法中一样,直接用byte [ ]去解密

 

2.在windows下能正常解密,但是相同的代码拷贝到linux下既失效。

解决方法:把getkey中的初始化SecureRandom,改成如下方式即可:

         SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                secureRandom.setSeed(MiddleKey.getBytes());
                keyGenerator.init(128,secureRandom);

 

你可能感兴趣的:(Java)