Java实现对称密钥算法
简介
对称密钥算法(英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。事实上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通信联系。与公开密钥加密相比,要求双方获取相同的密钥是对称密钥加密的主要缺点之一。
常见的对称加密算法有AES、ChaCha20、3DES、Salsa20、DES、Blowfish、IDEA、RC5、RC6、Camellia。对称加密的速度比公钥加密快很多,在很多场合都需要对称加密。
对称加密算法消息传递图示
对称密钥算法--DES
DES算法在98年之后不断的被破解,当下DES的加密已经不具备安全性了,所以现在一个新项目或者没有使用过加密算法的应用,在加密算法选型的时候不用考虑DES算法。DES目前只出现在一些介绍、案例或者一些遗留的软件或者硬件中。
在这里介绍下DES算法,因为DES在加密算法(尤其是对称加密算法)中的地位是非常高的。
DES(Data Encryption Standard)数据加密标准
| 密钥长度 |
默认 |
工作模式 |
填充方式 |
实现方 |
56 |
56 |
ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128 |
NoPadding、 PKCS5Padding、 ISO10126Padding |
JDK |
64 |
56 |
ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128 |
PKCS7Padding、 SO10126d2Padding、 X032Padding、 ISO7816d4Padding、 ZeroBytePadding |
Bouncy Castle |
DES加密示例:
package com.bity.des;import org.apache.commons.codec.binary.Hex;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import java.nio.charset.StandardCharsets;import java.security.InvalidKeyException;import java.security.Key;import java.security.NoSuchAlgorithmException;import java.security.spec.InvalidKeySpecException;import static java.lang.System.*;/*** <p>Title: JdkDes</p >* <p>Description: DES加密算法 </p >* <p>Company: http://www.agree.com</p >* <p>Project: security</p >** @author <a href="mailto:[email protected]">WEIQI</a>* @version 1.0* @date 2022-04-26 20:21*/public class JdkDes {private static final String SRC = "I'm DES encryption algorithm";public static void main(String[] args) {jdkDes();}/*** JDK-DES对称密钥算法实现** @author: <a href="mailto:[email protected]">WEIQI</a>* @date: 2022-04-26 20:41*/private static void jdkDes() {try {// generator KEYKeyGenerator keyGenerator = KeyGenerator.getInstance("DES");keyGenerator.init(56);SecretKey secretKey = keyGenerator.generateKey();byte[] bytesKey = secretKey.getEncoded();// convert KEYDESKeySpec desKeySpec = new DESKeySpec(bytesKey);SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");Key convertSecureKey = secretKeyFactory.generateSecret(desKeySpec);// encryptionCipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, convertSecureKey);byte[] result = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));out.println("encryption result is : " + Hex.encodeHexString(result));//decryptcipher.init(Cipher.DECRYPT_MODE, convertSecureKey);result = cipher.doFinal(result);out.println("decrypt result is : " + new String(result));} catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {e.printStackTrace();}}}
运行结果如下:
encryption result is : 97919bd6b4d1590e773fdc1100564f1fecb6d585cb80015b080bb75c29f15d4ddecrypt result is : I'm DES encryption algorithm
DES加密算法消息传递如下所示:
对称密钥算法--3重DES
3重DES的出现是因为DES算法是半公开的,这点恰好违反了柯克霍夫原则,安全性也有问题。3重DES对密码长度做了增强、迭代次数进行了提高,是目前实际应用中用得最多的。
3DES(Triple DESDESede)
| 密钥长度 |
默认 |
工作模式 |
填充方式 |
实现方 |
112 、 168 |
168 |
ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128 |
NoPadding、 PKCS5Padding、 ISO10126Padding |
JDK |
128 、 192 |
168 |
ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128 |
PKCS7Padding、 SO10126d2Padding、 X032Padding、 ISO7816d4Padding、 ZeroBytePadding |
Bouncy Castle |
DES加密示例:
package com.bity.des;import org.apache.commons.codec.binary.Hex;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import javax.crypto.spec.DESedeKeySpec;import java.nio.charset.StandardCharsets;import java.security.InvalidKeyException;import java.security.Key;import java.security.NoSuchAlgorithmException;import java.security.spec.InvalidKeySpecException;import static java.lang.System.out;/*** <p>Title: Jdk3Des</p >* <p>Description: 3DES加密算法实践 </p >* <p>Company: http://www.agree.com</p >* <p>Project: security</p >** @author <a href="mailto:[email protected]">WEIQI</a>* @version 1.0* @date 2022-04-26 20:55*/public class Jdk3Des {private static final String SRC = "I'm 3DES encryption algorithm";public static void main(String[] args) {jdk3Des();}/*** JDK-DES对称密钥算法实现** @author: <a href="mailto:[email protected]">WEIQI</a>* @date: 2022-04-26 20:41*/private static void jdk3Des() {try {// generator KEYKeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");keyGenerator.init(168);SecretKey secretKey = keyGenerator.generateKey();byte[] bytesKey = secretKey.getEncoded();// convert KEYDESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey);SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede");Key convertSecureKey = secretKeyFactory.generateSecret(desKeySpec);// encryptionCipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, convertSecureKey);byte[] result = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));out.println("encryption result is : " + Hex.encodeHexString(result));//decryptcipher.init(Cipher.DECRYPT_MODE, convertSecureKey);result = cipher.doFinal(result);out.println("decrypt result is : " + new String(result));} catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {e.printStackTrace();}}}
运行结果:
encryption result is : c44fb80f098ba6d601032abd18b71cee83f7b533b053c227350cfc89892143cbdecrypt result is : I'm 3DES encryption algorithm
对称密钥算法--AES
由于DES安全性没有了保证,3DES性能比较低,所以出现了AES对称加密算法。AES是目前使用最多的对称加密算法,AES至今尚未被破解。该算法通常用于移动通信系统的加密以及基于SSH协议的软件。
AES(Advanced Encryption Standard)
| 密钥长度 |
默认 |
工作模式 |
填充方式 |
实现方 |
128、192、256 |
128 |
ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128 |
NoPadding、 PKCS5Padding、 ISO10126Padding |
JDK |
128、192、256 |
128 |
ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到128、OFB、OFB8到128 |
PKCS7Padding、 ZeroBytePadding |
Bouncy Castle |
这里注意:JDK实现方256位密钥需要获得无政策限制权限文件。无政策限制文件是指因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制。
AES加密示例:
package com.bity.aes;import org.apache.commons.codec.binary.Base64;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import java.nio.charset.StandardCharsets;import java.security.InvalidKeyException;import java.security.Key;import java.security.NoSuchAlgorithmException;import static java.lang.System.*;/*** <p>Title: JdkAes</p >* <p>Description: </p >* <p>Company: http://www.agree.com</p >* <p>Project: security</p >** @author <a href="mailto:[email protected]">WEIQI</a>* @version 1.0* @date 2022-04-26 21:09*/public class JdkAes {private static final String SRC = "I'm AES encryption algorithm";public static void main(String[] args) {jdkAes();}/*** JDK-AES加密实现** @author: <a href="mailto:[email protected]">WEIQI</a>* @date: 2022-04-26 21:17*/private static void jdkAes() {try {// generator KEYKeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(128);SecretKey secretKey = keyGenerator.generateKey();byte[] bytesKey = secretKey.getEncoded();// convert KEYKey key = new SecretKeySpec(bytesKey, "AES");// encryptionCipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, key);byte[] result = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));out.println("aes encryption result is : " + Base64.encodeBase64String(result));//decryptcipher.init(Cipher.DECRYPT_MODE, key);result = cipher.doFinal(result);out.println("aes decrypt result is : " + new String(result));} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {e.printStackTrace();}}}
运行结果:
aes encryption result is : zbnnZOB0dwJH4V/zeNVbOEjDR5/ltFZXkqqZY7Y+JHw=aes decrypt result is : I'm AES encryption algorithm
对称密钥算法--PBE
PBE算法结合了消息摘要算法和对称加密算法的优点,对已有算法进行包装,形成了一个特殊的对称加密算法。
PBE算法消息通信
PBE(Password Based Encryption)基于口令的加密
| 算法 |
密钥长度 | 默认 |
工作方式 |
填充方式 |
实现 |
| PBEWithMD5AndDES | 64 |
64 |
CBC |
PKCS5Padding PKCS7Padding ISO10126Padding ZeroBytePadding |
BC |
| PBEWithMD5AndRC2 | 112 |
112 |
|||
| PBEWithSHA1AndDES | 64 |
64 |
|||
| PBEWithSHA1AndRC2 | 128 |
128 |
|||
| PBEWithSHAAndIDEA-CBC | 128 | 128 |
|||
| PBEWithSHAAnd2-KeyTripleDES-CBC | 128 | 128 |
|||
| PBEWithSHAAnd3-KeyTripleDES-CBC | 128 | 128 |
PBE加密示例
package com.bity.pbe;import org.apache.commons.codec.binary.Base64;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.PBEKeySpec;import javax.crypto.spec.PBEParameterSpec;import java.nio.charset.StandardCharsets;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.Key;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.security.spec.InvalidKeySpecException;/*** <p>Title: JdkPbe</p >* <p>Description: PBE算法实现 </p >* <p>Company: http://www.agree.com</p >* <p>Project: security</p >** @author <a href="mailto:[email protected]">WEIQI</a>* @version 1.0* @date 2022-04-26 21:37*/public class JdkPbe {private static final String SRC = "I'm PBE encryption algorithm";public static void main(String[] args) {jdkPbe();}private static void jdkPbe() {try {// 初始化盐SecureRandom random = new SecureRandom();byte[] salt = random.generateSeed(8);// 口令和密钥String token = "Abcd1234!@#$";PBEKeySpec pbeKeySpec = new PBEKeySpec(token.toCharArray());SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");Key key = factory.generateSecret(pbeKeySpec);// 加密PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 100);Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES");cipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpec);byte[] result = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));System.out.println("pbe encryption result is : " + Base64.encodeBase64String(result));// 解密cipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpec);result = cipher.doFinal(result);System.out.println("pbe decrypt reult is : " + new String(result));} catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {e.printStackTrace();}}}
运行结果:
pbe encryption result is : 1VcN0rTwdFxFgtKtedxnD2Zr3em8/tKWmg0vW1W6Abk=pbe decrypt reult is : I'm PBE encryption algorithm
以上就是对称加密算法的基本内容,在实际工作中可以根据业务需要,选择相应的对称加密算法对数据进行加密保护。
