笔者学识浅薄,对加密的研究也只是刚刚起步,很多深入的知识有待挖掘,还没有到达研究原理的高度和深度。文章的重心在简单的应用Java中AES中的一种加密方式。
第一 创建一个Java 对象,这个Password对象有4个属性分别是 明文、密文、密钥、和加密算法。
public class Password {
/**
* 密文16进制字符串
*/
private String ciphertext;
/**
* 明文
*/
private String plaintext;
/**
* 密钥 16进制密钥
*/
private String secretKey;
/**
* 算法
*/
private String algorithm;
public String getAlgorithm() {
return algorithm;
}
public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
}
public String getCiphertext() {
return ciphertext;
}
public String getPlaintext() {
return plaintext;
}
public String getSecretKey() {
return secretKey;
}
public void setCiphertext(String ciphertext) {
this.ciphertext = ciphertext;
}
public void setPlaintext(String plaintext) {
this.plaintext = plaintext;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
}
第二 创建一个工具类Convert,来处理字节数组和十六进制字符串之间的相互转化。
public class Convert {
private static Convert convert;
private Convert() {
}
/**
*
* @description TODO 通过这样的方式来创建单列
* @return
* @return Convert
*/
public static Convert getInstance() {
if (convert == null)
convert = new Convert();
return convert;
}
/**
*
* @description TODO 将字节数组转化为十六进制字符串
* @param bytes
* @return
* @return String
*/
public static String bytes2HexString(byte[] bytes) {
if (bytes != null && bytes.length > 0) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() < 2)
hex = '0' + hex;
sb.append(hex.toUpperCase());
}
return sb.toString();
}
return null;
}
/**
*
* @description TODO 十六进制字符串转字节数组
* @param hexString
* @return
* @return byte[]
*/
public static byte[] hexStringToBytes(String hexString) {
if (hexString != null && !"".equals(hexString)) {
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
bytes[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return bytes;
}
return null;
}
/**
*
* @description TODO 字符转化字节
* @param c
* @return
* @return byte
*/
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
}
第三步创建我们的加密和解密的AES算法类
public interface Algorithm {
public Password encrypt(Password password) throws Exception;
public Password decrypt(Password password) throws Exception;
}
public class AESAlgorithm implements Algorithm {
private static int AES_KEY_SIZE = 128;
@Override
public Password encrypt(Password password) throws Exception {
/**
* 生成密钥
*/
KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(AES_KEY_SIZE);
SecretKey key = generator.generateKey();
/**
* 将密钥转为16进制字符串
*/
password.setSecretKey(Convert.bytes2HexString(key.getEncoded()));
Cipher cipher = Cipher
.getInstance(EncryptionAlgorithm.AES_CBC_PKCS5_PADDING.getAlgorithm());
AlgorithmParameterSpec iv = new IvParameterSpec(getIV());
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] encryptBytes = cipher.doFinal(password.getPlaintext().getBytes(
"UTF-8"));
/**
* 将加密结果转化为16进制字符串
*/
password.setCiphertext(Convert.bytes2HexString(encryptBytes));
return password;
}
@Override
public Password decrypt(Password password) throws Exception {
if (password.getCiphertext() != null && password.getCiphertext() != null
&& !"".equals(password.getSecretKey())
&& !"".equals(password.getCiphertext())) {
byte[] ciphertext = Convert.hexStringToBytes(password.getCiphertext());
byte[] key = Convert.hexStringToBytes(password.getSecretKey());
Key secretKey = new SecretKeySpec(key, "AES");
AlgorithmParameterSpec iv = new IvParameterSpec(getIV());
Cipher cipher = Cipher
.getInstance(EncryptionAlgorithm.AES_CBC_PKCS5_PADDING.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] decryptBytes = cipher.doFinal(ciphertext);
password.setPlaintext(new String(decryptBytes, "UTF-8"));
return password;
}
return password;
}
static byte[] getIV() {
String iv = "1234567812345678"; // IV length: must be 16 bytes long
return iv.getBytes();
}
}
第四 枚举类型来穷举AES加密的四种加密方式
public enum EncryptionAlgorithm {
AES_CBC_NO_PADDING("AES/CBC/NoPadding"),
AES_CBC_PKCS5_PADDING("AES/CBC/PKCS5Padding"),
AES_ECB_NO_PADDING("AES/ECB/NoPadding"),
AES_ECB_PKCS5_PADDING("AES/ECB/PKCS5Padding");
private String algorithm;
private EncryptionAlgorithm(String algorithm) {
this.algorithm = algorithm;
}
public String getAlgorithm() {
return algorithm;
}
}
1、AES加密后的密钥和密文为了方便记录存储,转化为十六进制字符串;
2、密钥和密文两个条件来解密还原成明文;
3、文中只是简单介绍了AES一种方式(AES/ECB/PKCS5Padding)的加密方式的应用。