![f63e592265febe9d00fcda53a256a9c9.png](https://i-blog.csdnimg.cn/blog_migrate/dbe0c02beeb126a0cab823816f4abc8c.jpeg)
1、引言
PBE,是Password Based Encryption的缩写,即“基于口令的加密算法”。
IETF制定了两个相关的标准:
rfc2898:PKCS #5: Password-Based Cryptography Specification Version 2.0
rfc8018:PKCS #5: Password-Based Cryptography Specification Version 2.1
这两个标准对MAC和PBE算法制定了规范,有兴趣的朋友可以仔细阅读。
2、PBE的原理
前面第8讲介绍过不可逆加密算法HMAC,HMAC其实算不上独立的不可逆加密算法,而是一种融合了密钥和其它不可逆加密算法的实现。
PBE和HMAC比较类似,并不是一个独立的对称加密算法,而是一种融合了口令、盐值、哈希算法和其它对称加密算法的实现。
使用PBE进行加密操作的原理如下图所示:
![c856ad80fb90bdec0fc1eda64031944b.png](https://i-blog.csdnimg.cn/blog_migrate/6cdda8c4251dc36e8b49d2572e9b7573.jpeg)
PBE的实现原理,其实是根据口令,生成密钥,然后利用生成的密钥进行加密或解密操作。
3、使用JDK的PBE功能
在JDK中,实现了PBE功能。下面的示例代码,使用了基于MD5和DES算法的PDE实现:
package com.flying.pbe;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import javax.crypto.*;import javax.crypto.spec.PBEKeySpec;import javax.crypto.spec.PBEParameterSpec;import java.security.*;import java.security.spec.InvalidKeySpecException;@SpringBootApplicationpublic class PbeApplication { public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException { SpringApplication.run(PbeApplication.class, args); //密码为my_password String password = "my_password"; printBytes("The password of PBE is", password.getBytes()); PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHMD5andDES"); Key key = factory.generateSecret(pbeKeySpec); //随机生成盐值 SecureRandom random = new SecureRandom(); byte[] saltBytes = random.generateSeed(8); printBytes("Salt of PBE is ", saltBytes); byte[] plainBytes = {'h', 'e', 'l', 'l', 'o'}; printBytes("Plain text of PBE is", plainBytes); //对hello进行加密 PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(saltBytes, 100); Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES"); cipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpec); byte[] encryptedBytes = cipher.doFinal(plainBytes); printBytes("Encrypted text of PBE is", encryptedBytes); //进行解密操作,看是否可以得到hello cipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpec); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); printBytes("Decrypted text of PBE is", decryptedBytes); } private static void printBytes(String prompt, byte[] bytes){ if (prompt == null || bytes == null){ return; } System.out.print(prompt + ":"); for (int i=0; i
程序的运行情况如下:
![7d4da667325581a5b8cce83154d57b41.png](https://i-blog.csdnimg.cn/blog_migrate/c29af2ee499880aafa305065718913a4.jpeg)
4、程序逻辑解释
上面程序运行的逻辑如下:
(1)输入PBE的密码是6D 79 5F 70 61 73 73 77 6F 72 64(即“my_password”);
(2)算法为PBEWITHMD5andDES,即基于MD5和DES算法的PBE实现;
(3)使用的盐值是一个随机生成的值2D D3 71 BC 99 F3 BF 37;
(4)要加密的原文是68 65 6C 6C 6F(即“hello”);
(5)加密后得到E6 BF E9 E9 4D 3A DF 51;
(6)对E6 BF E9 E9 4D 3A DF 51解密后得到68 65 6C 6C 6F(即“hello”)。