Java加密简单了解
最近需要用到AES和rsa加密,学了下Java加密,写了点东西,记录下。
这是简单的字符串加密,文件加密等后面再发。
Java如何加密
一、先上代码简单的加解密
1.加密
/**
* base 64 encodes
* @param bytes 待编码的byte[]
* @return 编码后的base 64 code
*/
public static String base64Encode(byte[] bytes) {
return Base64.encodeBase64String(bytes);
}
/**
* AES加密
* @param content 待加密的内容
* @param encryptKey 加***
* @return 加密后的bytes[]
* @throws Exception
*/
public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
Cipher cipher = Cipher.getInstance(Message.ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(),"AES"));
return cipher.doFinal(content.getBytes("utf-8"));
}
/**
* AES加密为base 64 code
* @param content 待加密的内容
* @param encryptKey 加***
* @return 加密后的base 64 code
* @throws Exception
*/
public static String aesEncrypt(String content, String encryptKey) throws Exception{
return base64Encode(aesEncryptToBytes(content, encryptKey));
}
2.解密
/**
* base 64 decode
* @param base64Code 待解码的base 64 code
* @return 解码后的byte[]
* @throws IOException
*/
public static byte[] base64Decode(String base64Code) throws IOException {
return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code);
}
/**
* AES解密
* @param encryptBytes 待解密的byte[]
* @param decryptKey 解***
* @return 解密后的String
* @throws Exception
*/
public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception{
Cipher cipher = Cipher.getInstance(Message.ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
/**
* 将base 64 code解密
* @param encryptAtr 待解密的base 64 code
* @param decryptKey 解***
* @return解密后的String
* @throws Exception
*/
public static String aesDecrypt(String encryptAtr,String decryptKey) throws Exception{
return StringUtils.isEmpty(encryptAtr) ? null : aesDecryptByBytes(base64Decode(encryptAtr), decryptKey);
}
3.代码解释
上面简单实现了AES(“AES/ECB/PKCS5Padding”)的加密和解密。可以看到到代码中主要用到的是cipher对象,并有以下调用
(1)新建Cipher对象时需要传入一个参数"AES/ECB/PKCS5Padding"。
(2)cipher对象使用之前还要初始化,共两个参数(“加密模式或者解密模式”,“**”)。
(3)调用数据转换:cipher.doFinal(content),其中content是一个byte数组。
实际上Cipher类实现了多种加密算法,在创建Cipher对象时,传入不同的参数就可以进行不同的加密算法,而这些算法不同的地方只是创建**的方法不同而已。
如传入"AES/ECB/PKCS5Padding"就可以进行AES加密。传入"DESede/CBC/NoPadding"可以进行DES3加密。
要了解Java自带的加密算法,可以参考JDK文档的附录:点我进入~~~~
二、Java的Cipher类
1.Cipher类提供了加密和解密的功能
常用的使用Cipher类完成AES、DES、DES3和RSA加密。
获取Cipher类的对象:Cipher cipher = Cipher.getInstance(“DES/CBC/PKCS5Padding”);参数按“算法/模式/填充模式”,有以下参数
- AES/CBC/NoPadding (128)
- AES/CBC/PKCS5Padding (128)
- AES/ECB/NoPadding (128)
- AES/ECB/PKCS5Padding (128)
- DES/CBC/NoPadding (56)
- DES/CBC/PKCS5Padding (56)
- DES/ECB/NoPadding (56)
- DES/ECB/PKCS5Padding (56)
- DESede/CBC/NoPadding (168)
- DESede/CBC/PKCS5Padding (168)
- DESede/ECB/NoPadding (168)
- DESede/ECB/PKCS5Padding (168)
- RSA/ECB/PKCS1Padding (1024, 2048)
- RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
- RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
(1)加密算法有:AES、DES、DESede(DES3)和RSA四种
(2)模式有CBC(有向量模式)和ECB(无向量模式),向量模式可以简单理解为偏移量,使用CBC模式需要定义一个IvParameterSpec对象。
(3)填充模式: - NoPadding:加密内容不足8位用0不足8位,Cipher类不提供补位功能,需要自己实现代码给加密内容添加0,如{1,1,1,0,0,0,0,0}
- PKCS5Padding:加密内容不足8位用余位数补足8位,如{65,65,65,34,4,4,4,4}刚好8位补齐。
2.Cipher对象需要初始化
init(int opmode, Key key, AlgorithmParameterSpec params)
(1)opmode:Cipher.ENCRYPT_MODE(加密模式)和Cipher.DECRYPT_MODE(解密模式)
(2)key:**使用传入的**种子构造出一个**,可以使用SecretKeySpec、KeyGenerator和KeyPairGenerator创建**,其中
- SecretKeySpec和KeyGenerator支持AES、DES、DESede三种加密算法创建**。
- KeyPairGenerator支持RSA加密创建算法**。
(3)params:使用CBC模式时必须传入该参数,一般使用IvParameterSpec创建iv对象
3.加密或解密
byte[] bytes = cipher.doFinal(content);
返回结果为byte数组,如果直接使用new String(bytes)封装成字符串,则会出现乱码。
一般有两种处理方法:转换为base64的字符串或者转换为16进制的字符串。
3.1转换为base64
使用apache下的Base64类进行封装即可,Base64.encodeBase64String(result)结果就是ZpsMeHzAo7CMtKoi9diExxByn6v这样。
3.2转换为16进制
编码实现,即编码实现将2进制转换为16进制。
/**
* 16进制工具类
*/
public class HexUtil {
private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/**
* 十六进制转化为二进制
*/
public static byte[] hexStrToByteArray(String hexString) {
if (hexString == null) {
return null;
}
if (hexString.length() == 0) {
return new byte[0];
}
byte[] byteArray = new byte[hexString.length() / 2];
for (int i = 0; i < byteArray.length; i++) {
String subStr = hexString.substring(2 * i, 2 * i + 2);
byteArray[i] = ((byte) Integer.parseInt(subStr, 16));
}
return byteArray;
}
/**
* 二进制转化为十六进制
*/
public static String byteArrayToHexStr(byte[] byteArray) {
if (byteArray == null) {
return null;
}
char[] hexChars = new char[byteArray.length * 2];
for (int j = 0; j < byteArray.length; j++) {
int v = byteArray[j] & 0xFF;
hexChars[j * 2] = HEX_CHARS[v >>> 4];
hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F];
}
return new String(hexChars);
}
}
结果就是04A2784A45234B…这种样子啦。
上一篇: 1014 Waiting in Line
下一篇: 队列实现栈,栈实现队列