作者:郭嘉
邮箱:[email protected]
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWell
【Java安全技术探索之路系列:Java可扩展安全架构】之一:Java可扩展安全架构开篇
【Java安全技术探索之路系列:Java可扩展安全架构】之二:JCA(一):JCA架构介绍
【Java安全技术探索之路系列:Java可扩展安全架构】之三:JCA(二):JCA类和接口
【Java安全技术探索之路系列:Java可扩展安全架构】之四:JCA(三):JCA编程模型
【Java安全技术探索之路系列:Java可扩展安全架构】之五:JCE(一):JCE架构介绍
【Java安全技术探索之路系列:Java可扩展安全架构】之六:JCE(二):JCE类和接口
【Java安全技术探索之路系列:Java可扩展安全架构】之七:JCE(三):JCE编程模型
【Java安全技术探索之路系列:Java可扩展安全架构】之八:JCP(一):JCP架构介绍
【Java安全技术探索之路系列:Java可扩展安全架构】之九:JCP(二):JCP类和接口
【Java安全技术探索之路系列:Java可扩展安全架构】之十:JCP(三):JCP编程模型
【Java安全技术探索之路系列:Java可扩展安全架构】之十一:JSSE(一):JSSE架构介绍
【Java安全技术探索之路系列:Java可扩展安全架构】之十二:JSSE(二):JSSE类和接口
【Java安全技术探索之路系列:Java可扩展安全架构】之十三:JSSE(三):JSSE编程模型
【Java安全技术探索之路系列:Java可扩展安全架构】之十四:JAAS(一):JAAS架构介绍
【Java安全技术探索之路系列:Java可扩展安全架构】之十五:JAAS(二):JAAS类和接口
【Java安全技术探索之路系列:Java可扩展安全架构】之十六:JAAS(三):JAAS编程模型
【Java安全技术探索之路系列:Java可扩展安全架构】之十七:JGSS(一):JGSS架构介绍
【Java安全技术探索之路系列:Java可扩展安全架构】之十八:JGSS(二):JGSS类和接口
【Java安全技术探索之路系列:Java可扩展安全架构】之十九:JGSS(三):JGSS编程模型
【Java安全技术探索之路系列:Java可扩展安全架构】之二十:SASL(一):SASL架构介绍
【Java安全技术探索之路系列:Java可扩展安全架构】之二十一:SASL(二):SASL类和接口
【Java安全技术探索之路系列:Java可扩展安全架构】之二十二:SASL(三):SASL编程模型
加密是一种打乱消息、文件或程序的加密技术。JCE基本的加密和解密流程如下所示:
举例:DES算法加解密
package com.allenwells.jce;
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
/**
* DES安全编码组件
*
* @author AllenWells
* @version 1.0
*/
public abstract class DESEncryptor
{
/**
* 密钥算法
* Java 6 只支持56bit密钥
* Bouncy Castle 支持64bit密钥
*/
public static final String KEY_ALGORITHM = "DES";
/**
* 加密/解密算法 / 工作模式 / 填充方式
*/
public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5PADDING";
/**
* 转换密钥
*
* @param key
* 二进制密钥
* @return Key 密钥
* @throws Exception
*/
private static Key toKey(byte[] key) throws Exception
{
// 实例化DES密钥材料
DESKeySpec dks = new DESKeySpec(key);
// 实例化秘密密钥工厂
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance(KEY_ALGORITHM);
// 生成秘密密钥
SecretKey secretKey = keyFactory.generateSecret(dks);
return secretKey;
}
/**
* 解密
*
* @param data
* 待解密数据
* @param key
* 密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key) throws Exception
{
// 还原密钥
Key k = toKey(key);
// 实例化
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* 加密
*
* @param data
* 待加密数据
* @param key
* 密钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data, byte[] key) throws Exception
{
// 还原密钥
Key k = toKey(key);
// 实例化
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* 生成密钥
* Java 6 只支持56bit密钥
* Bouncy Castle 支持64bit密钥
*
* @return byte[] 二进制密钥
* @throws Exception
*/
public static byte[] initKey() throws Exception
{
/*
* 实例化密钥生成器
*
* 若要使用64bit密钥注意替换 将下述代码中的KeyGenerator.getInstance(CIPHER_ALGORITHM);
* 替换为KeyGenerator.getInstance(CIPHER_ALGORITHM, "BC");
*/
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
/*
* 初始化密钥生成器 若要使用64bit密钥注意替换 将下述代码kg.init(56); 替换为kg.init(64);
*/
kg.init(56, new SecureRandom());
// 生成秘密密钥
SecretKey secretKey = kg.generateKey();
// 获得密钥的二进制编码形式
return secretKey.getEncoded();
}
}
基于密码的加密(PBE)是一种根据密码推导加密密钥的技术,有助于攻击者发起的字典攻击及其他相关威胁。
举例:PBE加解密
package com.allenwells.jce;
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
/**
* PBE安全编码组件
*
* @author AllenWells
* @version 1.0
*/
public abstract class PBEEncryptor
{
/**
* Java 6 支持以下任意一种算法
*
*
* PBEWithMD5AndDES
* PBEWithMD5AndTripleDES
* PBEWithSHA1AndDESede
* PBEWithSHA1AndRC2_40
*
*/
public static final String ALGORITHM = "PBEWithMD5AndTripleDES";
/**
* 盐初始化
* 盐长度必须为8字节
*
* @return byte[] 盐
* @throws Exception
*/
public static byte[] initSalt() throws Exception
{
SecureRandom random = new SecureRandom();
return random.generateSeed(8);
}
/**
* 转换密钥
*
* @param password
* 密码
* @return Key 密钥
* @throws Exception
*/
private static Key toKey(String password) throws Exception
{
// 密钥材料转换
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
// 实例化
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
// 生成密钥
SecretKey secretKey = keyFactory.generateSecret(keySpec);
return secretKey;
}
/**
* 加密
*
* @param data
* 数据
* @param password
* 密码
* @param salt
* 盐
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data, String password, byte[] salt)
throws Exception
{
// 转换密钥
Key key = toKey(password);
// 实例化PBE参数材料
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
// 实例化
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 初始化
cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
// 执行操作
return cipher.doFinal(data);
}
/**
* 解密
*
* @param data
* 数据
* @param password
* 密码
* @param salt
* 盐
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, String password, byte[] salt)
throws Exception
{
// 转换密钥
Key key = toKey(password);
// 实例化PBE参数材料
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
// 实例化
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 初始化
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
// 执行操作
return cipher.doFinal(data);
}
}
消息验证码通常用于根据密钥检查信息的完整性和有效性。
举例:MAC算法实现
package com.allenwells.jce;
import java.security.Security;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
/**
* MAC消息摘要组件
*
* @author 梁栋
* @version 1.0
* @since 1.0
*/
public abstract class MACEncryptor
{
/**
* 初始化HmacMD2密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public static byte[] initHmacMD2Key() throws Exception
{
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD2");
// 产生秘密密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* HmacMD2消息摘要
*
* @param data
* 待做消息摘要处理的数据
* @param byte[] 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacMD2(byte[] data, byte[] key)
throws Exception
{
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacMD2");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* HmacMD2Hex消息摘要
*
* @param data
* 待做消息摘要处理的数据
* @param String
* 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static String encodeHmacMD2Hex(byte[] data, byte[] key)
throws Exception
{
// 执行消息摘要
byte[] b = encodeHmacMD2(data, key);
// 做十六进制转换
return new String(Hex.encode(b));
}
/**
* 初始化HmacMD4密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public static byte[] initHmacMD4Key() throws Exception
{
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD4");
// 产生秘密密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* HmacMD4消息摘要
*
* @param data
* 待做消息摘要处理的数据
* @param byte[] 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacMD4(byte[] data, byte[] key)
throws Exception
{
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacMD4");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* HmacMD4Hex消息摘要
*
* @param data
* 待做消息摘要处理的数据
* @param byte[] 密钥
* @return String 消息摘要
* @throws Exception
*/
public static String encodeHmacMD4Hex(byte[] data, byte[] key)
throws Exception
{
// 执行消息摘要
byte[] b = encodeHmacMD4(data, key);
// 做十六进制转换
return new String(Hex.encode(b));
}
/**
* 初始化HmacSHA224密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public static byte[] initHmacSHA224Key() throws Exception
{
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA224");
// 产生秘密密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* HmacSHA224消息摘要
*
* @param data
* 待做消息摘要处理的数据
* @param byte[] 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacSHA224(byte[] data, byte[] key)
throws Exception
{
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacSHA224");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* HmacSHA224Hex消息摘要
*
* @param data
* 待做消息摘要处理的数据
* @param byte[] 密钥
* @return String 消息摘要
* @throws Exception
*/
public static String encodeHmacSHA224Hex(byte[] data, byte[] key)
throws Exception
{
// 执行消息摘要
byte[] b = encodeHmacSHA224(data, key);
// 做十六进制转换
return new String(Hex.encode(b));
}
}
密钥协商协议使得多个通信方能够通过网络安全地交换密钥,从而进行加密通信。