1、对称密码算法简介
对称密码算法是当今应用范围最广,使用频率最高的加密算法。它不仅应用于软件行业,在硬件行业同样流行。各种基础设施凡是涉及到安全需求,都会优先考虑对称加密算法。
对称密码算法的加密密钥和解密密钥相同,对于大多数对称密码算法,加解密过程互逆。
(1)加解密通信模型
(2)特点:算法公开、计算量小、加密速度快、加密效率高
(3)弱点:双方都使用同样密钥,安全性得不到保证
对称密码有流密码和分组密码两种,但是现在普遍使用的是分组密码:
2、常用对称密码:
(1)DES(Data Encryption Standard,数据加密标准)
(2)3DES(Triple DES、DESede,进行了三重DES加密的算法)
(3)AES(Advanced Encryption Standard,高级数据加密标准,AES算法可以有效抵制针对DES的攻击算法)
三种算法的简单对比:
算法 | 密钥长度 | 默认密钥长度 | 工作模式 | 填充方式 |
DES | 56 | 56 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8-CFB128、OFB、OFB8-OFB128 | NoPadding、PKCS5Padding、ISO10126Padding |
3DES | 112、168 | 168 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8-CFB128、OFB、OFB8-OFB128 | NoPadding、PKCS5Padding、ISO10126Padding |
AES | 128、192、256 | 128 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8-CFB128、OFB、OFB8-OFB128 | NoPadding、PKCS5Padding、ISO10126Padding |
3、实例:
package com.its.common.crypto.symmetry;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* 对称加密(AES/DES/3DES) 推荐使用AES
*/
public class SymmetryUtil {
public static String ALGORITHM_AES = "AES";
public static String ALGORITHM_DES = "DES";
public static String ALGORITHM_3DES = "DESede";
public static String KEY = "QWE!@#123qwe123@*()342%";
/**
* 创建密钥key对象
*
* @param algorithm
* @param keysize
* @param key
* @return
* @throws NoSuchAlgorithmException
*/
public static SecretKey createKey(String algorithm, int keysize, String key) {
KeyGenerator keyGenerator = null;
SecretKey secretKey = null;
try {
keyGenerator = KeyGenerator.getInstance(algorithm);
keyGenerator.init(keysize, new SecureRandom(key.getBytes()));
secretKey = keyGenerator.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return secretKey;
}
public static byte[] encrypt(String algorithm, int keysize, String key, byte[] data) {
try {
SecretKey secretKey = createKey(algorithm, keysize, key);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptByte = cipher.doFinal(data);
return encryptByte;
} catch (Exception e) {
System.out.println("exception:" + e.toString());
}
return null;
}
public static byte[] decrypt(String algorithm, int keysize, String key, byte[] data) {
try {
SecretKey secretKey = createKey(algorithm, keysize, key);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptByte = cipher.doFinal(data);
return decryptByte;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String encrypt(String algorithm, int keysize, String key, String data) {
byte[] encryptByte = encrypt(algorithm, keysize, key, data.getBytes());
String encryptStr = encryptBASE64(encryptByte);
return encryptStr;
}
public static String decrypt(String algorithm, int keysize, String key, String data) {
byte[] decryptByte = decrypt(algorithm, keysize, key, decryptBASE64(data));
String decryptStr = new String(decryptByte);
return decryptStr;
}
/** 字节转字符 */
public static String byteToHexString(byte[] bytes) {
StringBuffer sb = new StringBuffer(bytes.length);
String sTemp;
for (int i = 0; i < bytes.length; i++) {
sTemp = Integer.toHexString(0xFF & bytes[i]);
if (sTemp.length() < 2) {
sb.append(0);
}
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}
/** 字节转字符 */
public static String encryptBASE64(byte[] data) {
return new BASE64Encoder().encodeBuffer(data);
}
/** 字符转字节 */
public static byte[] decryptBASE64(String data) {
try {
return new BASE64Decoder().decodeBuffer(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.its.test.crypto.symmetry;
import org.junit.Test;
import com.its.common.crypto.symmetry.SymmetryUtil;
public class SymmetryUtilTest {
/** 将字符加密后为字节--再将字节解密为字符 */
@Test
public void testByte() {
testAES();
testDES();
test3DES();
}
public void testAES() {
String data = "Tzz123456~!@#$%^&*()_+-={}|[]:'<>?,./asdkdk";
System.out.println("AES");
System.out.println("加密前:" + data);
byte[] encrypted = SymmetryUtil.encrypt(SymmetryUtil.ALGORITHM_AES, 128, SymmetryUtil.KEY, data.getBytes());
System.out.println("加密后:" + SymmetryUtil.byteToHexString(encrypted));
byte[] decrypted = SymmetryUtil.decrypt(SymmetryUtil.ALGORITHM_AES, 128, SymmetryUtil.KEY, encrypted);
System.out.println("解密后:" + new String(decrypted) + "\n");
}
public void testDES() {
String data = "PLaa456963~!@#$%^&*()_+-={}|[]:'<>?,./asdkdk";
System.out.println("DES");
System.out.println("加密前:" + data);
byte[] encrypted = SymmetryUtil.encrypt(SymmetryUtil.ALGORITHM_DES, 56, SymmetryUtil.KEY, data.getBytes());
System.out.println("加密后:" + SymmetryUtil.byteToHexString(encrypted));
byte[] decrypted = SymmetryUtil.decrypt(SymmetryUtil.ALGORITHM_DES, 56, SymmetryUtil.KEY, encrypted);
System.out.println("解密后:" + new String(decrypted) + "\n");
}
public void test3DES() {
String data = "Tzz123456~!@#$%^&*()_+-={}|[]:'<>?,./asdkdk";
System.out.println("3DES");
System.out.println("加密前:" + data);
byte[] encrypted = SymmetryUtil.encrypt(SymmetryUtil.ALGORITHM_3DES, 168, SymmetryUtil.KEY, data.getBytes());
System.out.println("加密后:" + SymmetryUtil.byteToHexString(encrypted));
byte[] decrypted = SymmetryUtil.decrypt(SymmetryUtil.ALGORITHM_3DES, 168, SymmetryUtil.KEY, encrypted);
System.out.println("解密后:" + new String(decrypted));
}
/** 将字符加密后为字符--再将字符解密为字符 */
@Test
public void testStr() {
testAESToStr();
}
public void testAESToStr() {
String data = "Tzz123456~!@#$%^&*()_+-={}|[]:'<>?,./asdkdk";
System.out.println("AES");
System.out.println("加密前:" + data);
String encrypted = SymmetryUtil.encrypt(SymmetryUtil.ALGORITHM_AES, 128, SymmetryUtil.KEY, data);
System.out.println("加密后:" + encrypted);
String decrypted = SymmetryUtil.decrypt(SymmetryUtil.ALGORITHM_AES, 128, SymmetryUtil.KEY, encrypted);
System.out.println("解密后:" + decrypted + "\n");
}
}