对称加密算法是当今应用范围最广,使用频率最高的加密算法。根据加密方式分为密码和分组密码,分组密码工作模式又可分为ECB、CBC、CFB、OFB和CTR等,密钥长度决定了加密算法的安全性。
DES算法的使用
DES(Data Encryption Standard,数据加密标准)算法,是对称加密算法的典型算法。由于密钥长度不足,衍生出了DESede算法(三重DES)。为替代DES算法,又有了AES算法。
基于DES算法的消息传递模型下面是对该算法JAVA实现的信息汇总:
算法 | 密钥长度 | 密钥长度默认值 | 工作模式 | 填充方式 | 备注 |
---|---|---|---|---|---|
DES | 56 | 56 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8至CFB128、OFB、OFB8至OFB128 | NoPadding、PKCS5Padding、ISO10126Padding | Java 6实现 |
DES | 64 | 同上 | 同上 | PKCS7Padding、ISO10126d2Padding、X932Padding、ISO7816d4Padding、ZeroBytePadding | Bouncy Castle实现 |
下面示例为DES算法的一个简要工具:
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;
public abstract class DESCoder {
/**
* 密钥算法 <br>
* Java 6 只支持56bit密钥 <br>
* 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);
}
/**
* 生成密钥 <br>
* Java 6 只支持56bit密钥 <br>
* Bouncy Castle 支持64bit密钥 <br>
*
* @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();
}
}
DESede算法,是针对DES密钥长度偏短和迭代次数偏少等问题的一次改良。但是该算法处理速度较慢,密钥计算时间较长,加密效率不高。
下面是对该算法JAVA实现的信息汇总:
算法 | 密钥长度 | 密钥长度默认值 | 工作模式 | 填充方式 | 备注 |
---|---|---|---|---|---|
DESede(Triple DES,3DES) | 112、168 | 168 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8至CFB128、OFB、OFB8至OFB128 | NoPadding、PKCS5Padding、ISO10126Padding | Java 6实现 |
DESede(Triple DES,3DES) | 128、192 | 同上 | 同上 | PKCS7Padding、ISO10126d2Padding、X932Padding、ISO7816d4Padding、ZeroBytePadding | Bouncy Castle实现 |
下面示例为DESede算法的一个简要工具:
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
public abstract class DESedeCoder {
/**
* 密钥算法
*/
public static final String KEY_ALGORITHM = "DESede";
/**
* 加密/解密算法 / 工作模式 / 填充方式
* Java 6支持PKCS5PADDING填充方式
* Bouncy Castle支持PKCS7Padding填充方式
*/
public static final String CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding";
/**
* 转换密钥
*
* @param key
* 二进制密钥
* @return Key 密钥
* @throws Exception
*/
private static Key toKey(byte[] key) throws Exception {
// 实例化DES密钥材料
DESedeKeySpec dks = new DESedeKeySpec(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);
/*
* 实例化
* 使用PKCS7Padding填充方式
* Cipher.getInstance(CIPHER_ALGORITHM, "BC");
*/
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);
/*
* 实例化
* 使用PKCS7Padding填充方式
* Cipher.getInstance(CIPHER_ALGORITHM, "BC");
*/
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* 生成密钥 <br>
*
* @return byte[] 二进制密钥
* @throws Exception
*/
public static byte[] initKey() throws Exception {
// 实例化
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
/*
* DESede 要求密钥长度为 112位或168位
*/
kg.init(168);
// 生成秘密密钥
SecretKey secretKey = kg.generateKey();
// 获得密钥的二进制编码形式
return secretKey.getEncoded();
}
}
AES算法的使用
DES算法漏洞的发现,且DESede算法的低效,从而诞生了AES(Advanced Encryption Standard,高级数据加密标准)算法。经过验证,AES已经能够有效抵御一直的针对DES算法的所有攻击方法(分差分攻击、相关密钥攻击等)。
下面是对该算法JAVA实现的信息汇总:
算法 | 密钥长度 | 密钥长度默认值 | 工作模式 | 填充方式 | 备注 |
---|---|---|---|---|---|
AES | 128、192、256 | 128 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8至CFB128、OFB、OFB8至OFB128 | NoPadding、PKCS5Padding、ISO10126Padding | Java 6实现 |
AES | 同上 | 同上 | 同上 | PKCS7Padding、ZeroBytePadding | Bouncy Castle实现 |
下面示例为AES算法的一个简要工具:
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public abstract class AESCoder {
/**
* 密钥算法
*/
public static final String KEY_ALGORITHM = "AES";
/**
* 加密/解密算法 / 工作模式 / 填充方式
* Java 6支持PKCS5Padding填充方式
* Bouncy Castle支持PKCS7Padding填充方式
*/
public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* 转换密钥
*
* @param key 二进制密钥
* @return Key 密钥
* @throws Exception
*/
private static Key toKey(byte[] key) throws Exception {
// 实例化AES密钥材料
SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
return secretKey;
}
/**
* 解密
*
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// 还原密钥
Key k = toKey(key);
/*
* 实例化
* 使用PKCS7Padding填充方式,按如下方式实现
* Cipher.getInstance(CIPHER_ALGORITHM, "BC");
*/
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);
/*
* 实例化
* 使用PKCS7Padding填充方式,按如下方式实现
* Cipher.getInstance(CIPHER_ALGORITHM, "BC");
*/
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* 生成密钥 <br>
*
* @return byte[] 二进制密钥
* @throws Exception
*/
public static byte[] initKey() throws Exception {
// 实例化
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
/*
* AES 要求密钥长度为 128位、192位或 256位
*/
kg.init(256);
// 生成秘密密钥
SecretKey secretKey = kg.generateKey();
// 获得密钥的二进制编码形式
return secretKey.getEncoded();
}
}
IDEA算法的使用
IDEA(International Data Encryption Algorithm,国际数据加密标准)算法,是在美国之外提出并发展起来的,避开了美国法律上对加密技术的诸多限制。该算法使用长度为128位的密钥,数据块大小为64位。从理论上讲,IDEA属于“强”加密算法,至今还没有出现对该算法的有效攻击算法。
下面是对该算法JAVA实现的信息汇总:
算法 | 密钥长度 | 密钥长度默认值 | 工作模式 | 填充方式 | 备注 |
---|---|---|---|---|---|
IDEA | 128 | 128 | ECB | PKCS5Padding、PKCS7Padding、ISO10126Padding、ZeroBytePadding | Bouncy Castle实现 |
下面示例为IDEA算法BC实现的一个简要工具:
import java.security.Key;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public abstract class IDEACoder {
/**
* 密钥算法
*/
public static final String KEY_ALGORITHM = "IDEA";
/**
* 加密/解密算法 / 工作模式 / 填充方式
*/
public static final String CIPHER_ALGORITHM = "IDEA/ECB/PKCS5Padding";
/**
* 转换密钥
*
* @param key
* 二进制密钥
* @return Key 密钥
* @throws Exception
*/
private static Key toKey(byte[] key) throws Exception {
// 生成秘密密钥
SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
return secretKey;
}
/**
* 解密
*
* @param data
* 待解密数据
* @param key
* 密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 还原密钥
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 {
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 还原密钥
Key k = toKey(key);
// 实例化
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* 生成密钥 <br>
*
* @return byte[] 二进制密钥
* @throws Exception
*/
public static byte[] initKey() throws Exception {
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 实例化
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
// 初始化
kg.init(128);
// 生成秘密密钥
SecretKey secretKey = kg.generateKey();
// 获得密钥的二进制编码形式
return secretKey.getEncoded();
}
}
PBE算法的使用
PBE(Password Based Encryption,基于口令加密)算法,该算法没有密钥,而是用口令代替密钥。口令由用户自己掌管,采用盐(随机数)+ 重加密等方式保证数据安全性。
基于PBE算法的消息通讯模型
PBE是对已知对称加密算法的一个包装,它在做加密/解密时,实际使用了DES或AES等其他对称加密算法做了相应的操作,常见算法如PBEWithMD5AndDES。
下面是对该算法JAVA实现的信息汇总:
算法 | 密钥长度 | 密钥长度默认值 | 工作模式 | 填充方式 | 备注 |
---|---|---|---|---|---|
PBEWithMD5AndDES | 56 | 56 | CBC | PKCS5Padding | java6实现 |
PBEWithMD5AndTripeDES | 112、168 | 168 | 同上 | 同上 | 同上 |
PBEWithSHA1AndDESede | 112、168 | 168 | 同上 | 同上 | 同上 |
PBEWithSHA1AndRC2_40 | 40至1024 | 128 | 同上 | 同上 | 同上 |
PBEWithMD5AndDES | 64 | 64 | 同上 | PKCS5Padding、PKCS7Padding、ISO10126Padding、ZeroBytePadding | BouncyCastle实现 |
PBEWithMD5AndRC2 | 128 | 128 | 同上 | 同上 | 同上 |
PBEWithSHA1AndDES | 64 | 64 | 同上 | 同上 | 同上 |
PBEWithSHA1AndRC2 | 128 | 128 | 同上 | 同上 | 同上 |
PBEWithSHAAndIDEA-CBC | 128 | 128 | 同上 | 同上 | 同上 |
PBEWithSHAAnd2-KeyTripleDES-CBC | 128 | 128 | 同上 | 同上 | 同上 |
PBEWithSHAAnd3-KeyTripleDES-CBC | 192 | 192 | 同上 | 同上 | 同上 |
PBEWithSHAAnd128BitRC2-CBC | 128 | 128 | 同上 | 同上 | 同上 |
PBEWithSHAAnd40BitRC2-CBC | 40 | 40 | 同上 | 同上 | 同上 |
PBEWithSHAAnd128BitRC4 | 128 | 128 | 同上 | 同上 | 同上 |
PBEWithSHAAnd40BitRC4 | 40 | 40 | 同上 | 同上 | 同上 |
PBEWithSHAAndTwofish-CBC | 256 | 256 | 同上 | 同上 | 同上 |
下面是PBE算法的一个示例:
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;
import static org.junit.Assert.*;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
public abstract class PBECoder {
/**
* Java 6 支持以下任意一种算法
*
* <pre>
* PBEWithMD5AndDES
* PBEWithMD5AndTripleDES
* PBEWithSHA1AndDESede
* PBEWithSHA1AndRC2_40
* </pre>
*/
public static final String ALGORITHM = "PBEWithMD5AndTripleDES";
/**
* 盐初始化<br>
* 盐长度必须为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);
}
@Test
public void test() throws Exception {
String inputStr = "PBE";
System.err.println("原文:" + inputStr);
byte[] input = inputStr.getBytes();
String pwd = "majx2@meicloud.com";
System.err.println("密码:\t" + pwd);
// 初始化盐
byte[] salt = PBECoder.initSalt();
System.err.println("盐:\t" + Base64.encodeBase64String(salt));
// 加密
byte[] data = PBECoder.encrypt(input, pwd, salt);
System.err.println("加密后:\t" + Base64.encodeBase64String(data));
// 解密
byte[] output = PBECoder.decrypt(data, pwd, salt);
String outputStr = new String(output);
System.err.println("解密后:\t" + outputStr);
// 校验
assertEquals(inputStr, outputStr);
}
}
网友评论