irpas技术客

Java实现对称密钥算法_编程之艺术_java 对称加密算法

大大的周 1380

简介

????????对称密钥算法(英语: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://·">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:weiqi@agree.com.cn">WEIQI</a> * @date: 2022-04-26 20:41 */ private static void jdkDes() { try { // generator KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("DES"); keyGenerator.init(56); SecretKey secretKey = keyGenerator.generateKey(); byte[] bytesKey = secretKey.getEncoded(); // convert KEY DESKeySpec desKeySpec = new DESKeySpec(bytesKey); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES"); Key convertSecureKey = secretKeyFactory.generateSecret(desKeySpec); // encryption Cipher 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)); //decrypt cipher.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 : 97919bd6b4d1590e773fdc1100564f1fecb6d585cb80015b080bb75c29f15d4d decrypt 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://·">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:weiqi@agree.com.cn">WEIQI</a> * @date: 2022-04-26 20:41 */ private static void jdk3Des() { try { // generator KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede"); keyGenerator.init(168); SecretKey secretKey = keyGenerator.generateKey(); byte[] bytesKey = secretKey.getEncoded(); // convert KEY DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede"); Key convertSecureKey = secretKeyFactory.generateSecret(desKeySpec); // encryption Cipher 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)); //decrypt cipher.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 : c44fb80f098ba6d601032abd18b71cee83f7b533b053c227350cfc89892143cb decrypt 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://·">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:weiqi@agree.com.cn">WEIQI</a> * @date: 2022-04-26 21:17 */ private static void jdkAes() { try { // generator KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(128); SecretKey secretKey = keyGenerator.generateKey(); byte[] bytesKey = secretKey.getEncoded(); // convert KEY Key key = new SecretKeySpec(bytesKey, "AES"); // encryption Cipher 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)); //decrypt cipher.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)基于口令的加密?

算法密钥长度默认工作方式填充方式实现PBEWithMD5AndDES6464

CBC

PKCS5Padding

PKCS7Padding

ISO10126Padding

ZeroBytePadding

BC

PBEWithMD5AndRC2112112PBEWithSHA1AndDES6464PBEWithSHA1AndRC2128128PBEWithSHAAndIDEA-CBC128128PBEWithSHAAnd2-KeyTripleDES-CBC128128PBEWithSHAAnd3-KeyTripleDES-CBC128128

????????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://·">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

????????以上就是对称加密算法的基本内容,在实际工作中可以根据业务需要,选择相应的对称加密算法对数据进行加密保护。

附加

????????关于加解密相关系列文章会在微信公众号《编程之艺术》中每天连载分享,感兴趣的朋友可以关注下,可以及时获取最新文章连载信息。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

?


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #JAVA #对称加密算法