对称加密key是一个byte数组,如AES256算法的key是一个32字节的数组,普通的加密软件由用户输入加密口令。如果由用户输入口令,进行加密/解密,需要用到PBE算法。

1.PBE:Password Based Encryption

  • 由用户输入口令,采用随机数杂凑计算出密钥再进行加密
  • Password:用户口令,例如“hello123”
  • Salt:随机生成的byte[]
  • Key:由随机的salt和password计算而成:generate(byte[] salt,String password)

2.AES和PBE的对比:

AES

    byte[] message = ...;
byte[] key = generated16Bytes();//算法随机生成16字节的数组
byte[] encrypted = aes128_encrypt(key, message);

PBE

    byte[] message = ...;
String password = "hello123";
byte[] salt = random16Bytes();//随机产生一个16字节的salt
//为什么引入salt?因为用户输入的口令通常都很短,引入一个随机的salt,既可增加口令的长度,还可以让相同的口令生成不同的key,从而提高安全性。
byte[] key = generated16BytesFrom(password, salt);
byte[] encrypted = aes128_encrypt(key,message);

3.代码示例:salt不固定

package com.testList;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Base64; public class SplitString {
static final String CIPHER_NAME = "PBEwithSHA1and128bitAES-CBC-BC";
//加密
public static byte[] encrypt(String password, byte[] salt, byte[] input) throws GeneralSecurityException {
//传入char数组,获取一个PBEKeySpec的对象keySpec
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
//获取SecretKeyFactory对象skeyFactory
SecretKeyFactory skeyFactory = SecretKeyFactory.getInstance(CIPHER_NAME);
//传入keySpec,获取密钥:SecretKey类型的示例skey
SecretKey skey = skeyFactory.generateSecret(keySpec);
//将salt和用户输入的口令做1000次循环,获取PBEParameterSpec类型示例pbesp
PBEParameterSpec pbeps = new PBEParameterSpec(salt, 1000);
Cipher cipher = Cipher.getInstance(CIPHER_NAME);
//初始化:指定加密模式,传入skey,pbeps对象
cipher.init(Cipher.ENCRYPT_MODE, skey, pbeps);
return cipher.doFinal(input);
} public static byte[] decrypt(String password, byte[] salt, byte[] input) throws GeneralSecurityException {
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory skeyFactory = SecretKeyFactory.getInstance(CIPHER_NAME);
SecretKey skey = skeyFactory.generateSecret(keySpec);
PBEParameterSpec pbeps = new PBEParameterSpec(salt, 1000);
Cipher cipher = Cipher.getInstance(CIPHER_NAME);
//初始化:指定解密模式,传入skey,pbeps对象
cipher.init(Cipher.DECRYPT_MODE, skey, pbeps);
return cipher.doFinal(input);
} public static void main(String[] args) throws Exception{
//把BouncyCastle作为provider添加到java.security
Security.addProvider(new BouncyCastleProvider());
String message = "Hello world!encrypted using PBE!";
String password = "hello12345";
//16字节的salt
byte[] salt = SecureRandom.getInstanceStrong().generateSeed(16);
System.out.printf("salt:%032x\n",new BigInteger(1,salt));
byte[] data = message.getBytes(StandardCharsets.UTF_8);
byte[] encryted = encrypt(password,salt,data);
//打印Base64加密后的密文
System.out.println("encrypted:"+Base64.getEncoder().encodeToString(encryted));
byte[] decrypted = decrypt(password,salt,encryted);
System.out.println("decrypted:"+new String(decrypted,"UTF-8"));
}
}


由于每次的salt不一样,每次的密文也不一样。

4.salt固定

如果把salt固定,就得到了一个通用的口令加密软件。

只有同事破解了salt+口令,才能解密。而salt为128为随机数,很难被破解

5.总结:

  • PBE算法通过用户口令和随机salt计算key然后再加密
  • key通过口令和随机salt计算出,提高了安全性
  • PBE算法内部使用的仍然是标准对称加密算法(例如AES)

最新文章

  1. autocomplete的使用
  2. web开发-给即将毕业实习生的一点面试经验
  3. IE的安全性设定增加“我的电脑”的安全性设定
  4. 《redis-php中文参考手册》
  5. C语言 段位
  6. CSS3实现轮播图效果
  7. GD库使用小结---1
  8. centos6.5 64位 openvpn安装配置
  9. [转] c#多线程(UI线程,控件显示更新) Invoke和BeginInvoke 区别
  10. AU3学习笔记
  11. phpcmsV9手机站内容页有时内容不显示
  12. 多线程下System.Security.Cryptography.Aes CreateDecryptor报“Safe handle has been closed”的解决方案
  13. 如何解决RK3168或者RK系列MASKROM的问题
  14. win10安装配置nodejs
  15. 通用唯一识别码UUID
  16. 《剑指offer》从上往下打印二叉树
  17. VS项目启动后 提示ID为*******的进程当前未运行
  18. Adding a struct into an array(stackoverflow)
  19. H5开发中遇到的问题及解决办法
  20. java 创建最大堆

热门文章

  1. leetcode-421-数组中两个数的最大异或值*(前缀树)
  2. JavaScript中的表单编程
  3. php 扫描url死链接 \033[31m ANSI Linux终端输出带颜色
  4. Docker系列(一):Docker简单介绍
  5. Python3简介
  6. C# 中的三个高级参数 ref
  7. ztree 树状图——例
  8. Java开发系列-电子邮箱
  9. 搭建react的vw架构时候报 Cannot load preset "advanced".
  10. Codeforces 839D Winter is here