PBE的随笔

建议先看文章做初步了解:Password-Based Encryption (PBE)_厚积薄发者,轻舟万重山-CSDN博客

补充:

  • 因为具备密码学安全意义的密钥对于人来说是很难记忆的,所以密钥保存的安全性也需要慎重考虑,2022年建议使用的密钥安全强度已经是256bit起(当然128按照当前的算力也是有生之年系列,但是随着算力的提升,如果系统准备用10年以上,建议安全强度256bit,十年以内可以使用128bit);
  • 但是口令很容易,一段具有意义的文本对用户来说记忆是很容易的
  • 如何通过弱口令接近或达到密钥的安全强度?这就是PBE的价值

我用JDK中现役、常见的PBE算法PBEWithHmacSHA256AndAES_128为例作简述,简述思路如下:

  1. 先看看JDK中PBEWithHmacSHA256AndAES_128的应用代码;
  2. 通过应用代码来简述PBE过程;
  3. 通过应用代码和PBE过程来简述安全性;

应用代码

package wxy.secret;

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

/**
 * PBEWithHmacSHA256AndAES_128 示例代码
 * @author 王大锤
 * @date 2022年2月15日
 */
public class PBEDemo {
	private static String PBE_MODE = "PBEWithHmacSHA256AndAES_128";
	private static SecureRandom random = new SecureRandom();
	private static int DEFAULT_ITERATION_COUNT = 1000;

	/**
	 * 生成随机salt
	 * @param seed
	 * @return
	 */
	public static byte[] initSalt(int seed) {
		return random.generateSeed(seed);
	}

	/**
	 * PBEWithHmacSHA256AndAES_128中AES默认是CBC模式,分组128bit,初始化向量也是128bit
	 * @param length 16字节
	 * @return
	 */
	public static byte[] initIV(int length) {
		return random.generateSeed(length);
	}

	/**
	 * 虽然是生成SecretKey对象,但实际上这并不是pbe的密钥
	 * 你通过SecretKey.getEncoded方法拿到密钥的字节数组,你会发现和password.toCharArray是一样
	 * 实际上,这一步得到的密钥的字节数组就是口令password字符编码的二进制
	 * @param password
	 * @return
	 * @throws Exception
	 */
	public static SecretKey genereateKey(String password) throws Exception {
		PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
		return SecretKeyFactory.getInstance(PBE_MODE).generateSecret(pbeKeySpec);
	}

	/**
	 * 注意加密方法每次调用都要传入salt和iv
	 * @param key 其实是用户口令password的字符编码
	 * @param salt 随机salt
	 * @param iv AES CBC模式需要的初始化向量,128bit
	 * @param data 待加密数据
	 * @return pbe密文
	 * @throws Exception
	 */
	public static byte[] encryption(SecretKey key, byte[] salt, byte[] iv, byte[] data) throws Exception {
		Cipher cipher = Cipher.getInstance(PBE_MODE);
		IvParameterSpec ivp = new IvParameterSpec(iv);
		PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, DEFAULT_ITERATION_COUNT, ivp);
		cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
		return cipher.doFinal(data);
	}

	/**
	 * 注意解密方法入参的salt和iv和加密的一致,都是可以公开的数据
	 * @param key 用户口令的字符编码的二进制
	 * @param salt 随机salt
	 * @param iv AES CBC模式需要的初始化向量
	 * @param data 密文
	 * @return 明文
	 * @throws Exception
	 */
	public static byte[] decryption(SecretKey key, byte[] salt, byte[] iv, byte[] data) throws Exception {
		Cipher cipher = Cipher.getInstance(PBE_MODE);
		IvParameterSpec ivp = new IvParameterSpec(iv);
		PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, DEFAULT_ITERATION_COUNT, ivp);
		cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
		return cipher.doFinal(data);
	}
}

看一看测试:

		String password = "my_csdn_blog";
		SecretKey key = PBEDemo.genereateKey(password);
		byte[] salt = PBEDemo.initSalt(32);
		byte[] iv = PBEDemo.initIV(16);
		
		String message = "关于Java pbe的简述";
		Charset UTF8 = Charset.forName("UTF-8");
		
		byte[] ciphertext = PBEDemo.encryption(key, salt, iv, message.getBytes(UTF8));
		HexStringTool.print(ciphertext);
		byte[] plaintext = PBEDemo.decryption(key, salt, iv, ciphertext);
		HexStringTool.print(plaintext);
		System.out.println(new String(plaintext, UTF8));
		
		System.out.println("-------------------");
		System.out.println("基于password生成的SecretKey对象实际就是口令的字符编码的二进制:");
		HexStringTool.print(password.getBytes());
		HexStringTool.print(key.getEncoded());

测试结果:

833459198d56b24c7d3392035075a8c41145c75b5ab326c2687c4e482a977e5b
e585b3e4ba8e4a61766120706265e79a84e7ae80e8bfb0
关于Java pbe的简述
-------------------
基于password生成的SecretKey对象实际就是口令的字符编码的二进制:
6d795f6373646e5f626c6f67
6d795f6373646e5f626c6f67

jdk加解密各种getInstance的入参字符串不需要记忆,懂得查就行了,例如本例PBEWithHmacSHA256AndAES_128,查询页面Java Security Standard Algorithm Names (oracle.com)各种类各种密码学术语的入参,会找这个页面就行了。

更多的信息,看Java Platform, Standard Edition Security Developer’s Guide, Release 15 (oracle.com)

PBE过程

图下图:

通过上面测试代码就能知道,通过口令password得到的SecreteKey对象并非加密密钥,实际上是password的字符编码的二进制。

实际上是两个步骤:

  1. 用户口令password、随机salt在单向散列函数SHA256中经过iterationCount次迭代,得到AES的密钥(这里你可能不理解,但是没关系,周末我写一篇Java中diffie-hellman密钥协商的文章,那里面会给出这个过程的代码示例,就两句代码,很简单的,那里是Oracle官方推荐的转换方式);
  2. 然后PBE中AES默认是CBC模式,密钥+分组模式的初始化向量IV对明文进行加密得到密文;
  3. 将密文、salt、iv和iterationCount发送给解密方,解密方根据事先共享的password就能解密出明文;

同样的,PBE属于对称加密,一样存在密钥共享的问题,也就是加密方和解密方如何共享口令password。

安全性

对于PBEWithHmacSHA256AndAES_128而言,PBE过程是:

  1. 用户口令+salt经过iterationCount次的散列函数SHA256迭代,生成AES的密钥;
  2. 根据AES(默认是CBC模式)的模式选择好初始化向量IV,明文+密钥经过AES cipher得到密文;

如果要爆破:

A.对于攻击者而言,直接选择攻击AES 128的密钥爆破出明文是不现实的,就当前的算力而言这还属于有生之年系列(假设一秒钟能做100亿次计算,接近2^33次方,一年365*24*60*60差不多3KW秒,2^(128-33)/3KW,即2^95/3KW,你可以算算是多少年,有生之年系列)

B.用户口令就弱得多了,而且salt、iv和iterationCount都是公开的,这么来看,pbe的安全强度似乎就相当于用户的弱口令了?

实际上直接攻击用户弱口令这个选择也很难:

  • iterationCount会加倍攻击者的攻击代价,iterationCount通常是1000次以上迭代,对用户来说加解密就是迭代一千次,而对攻击者来说,是要付出一千倍的代价;
  • salt一直在变化,虽然salt是可以公开的,但是每次调用encryption方法输入的salt都不一样,一次通信是很多个data[]片段组成,每个data[]片段的salt都不一样,所以生成的AES密码也不一样,所以攻击者付出极大的代价爆破了一个data[]片段,也拿不到完整的信息;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: VASP是一种常用的第一性原理计算软件,用于研究材料的电子结构和性质。在VASP中,使用赝势方法可以减少计算复杂度,提高计算效率。 赝势(pseudopotential)是一种通过与核心电子相互作用模拟全电子系统行为的方法。赝势文件中的PAW (Projected Augmented Wave)和PBE (Perdew-Burke-Ernzerhof)表示VASP计算中的两个重要参数。 PAW是一种将全电子波函数转换为缀加波(expansion)的方法。在PAW中,通过选择合适的投影函数,将核心电子的电子密度投影到虚拟平面上,同时用缀加波函数描述残余的电子态。PAW方法能够显著提高计算效率,同时准确保留了核心电子贡献。 PBE是一种广泛应用的交换-相关泛函。在VASP中,PBE泛函用于计算电子之间的交换和相关作用,从而确定材料的电子结构和性质。PBE泛函基于密度泛函理论,计算精度较高,适用于各种材料的研究。 VASP赝势文件中的PAW和PBE参数,代表了在计算中使用的赝势方法和泛函选择。通过合理设置这些参数,我们可以在VASP中进行高效准确的电子结构计算,研究材料的能带结构、态密度、电荷密度等性质,为理解和设计材料的功能奠定基础。 ### 回答2: VASP(Vienna Ab initio Simulation Package)是一种材料计算软件,用于通过第一性原理计算方法计算材料的物理和化学性质。赝势(Pseudopotential)是VASP中常用的方法之一,用于减小计算中在原子核附近陡峭变化的电子波函数。赝势文件是赝势方法计算中所需的输入文件,其中"PBE"是指采用“PBE”(Perdew-Burke-Ernzerhof)密度泛函理论作为交换相关泛函的基准。 PBE是一种常用的密度泛函理论方法,用于描述材料中电子的行为。它是基于局域密度逼近的原理,通过引入交换和相关泛函修正了LDA(局域密度近似)的不足。PBE方法比LDA更准确,可以更好地预测材料的结构、能带结构、能量和电子性质等。 对于VASP中的赝势方法,PAW(Projector Augmented Wave)是一种常用的赝势方法,它在计算中考虑了原子核附近的电子波函数的详细信息,并引入了一组投影算符来描述电子与原子核的相互作用。PAW赝势可以准确描述电子的行为,计算结果更可靠。 因此,VASP赝势文件paw pbe是用于赝势计算的输入文件,其中paw表示使用PAW赝势,pbe表示采用PBE密度泛函理论作为基准。通过使用这样的赝势文件,我们可以在VASP中进行准确可靠的密度泛函计算,得到材料的各种物理和化学性质的预测结果。 ### 回答3: VASP赝势文件PAW是一种计算物质性质的常用工具,常用于第一原理计算中。PAW代表赝原子波函数(Projector Augmented Wave),PBE代表泛函近似Perdew-Burke-Ernzerhof。 在VASP赝势文件中,PAW方法通过引入赝原子波函数来处理波函数的计算。原子核和赝原子核分别作用于真实的电子波函数和赝波函数,从而实现对真实系统的模拟。PAW方法有效地解决了真实电子波函数与计算中使用的平面波基组之间的不匹配问题。 而PBE泛函是一种基于密度泛函理论的交换-相关能密度泛函,用于近似交换-相关能的计算。PBE泛函广泛应用于材料科学、化学和物理等领域的密度泛函理论计算中。它能够较好地描述材料的结构、能量、电子结构和电子态密度等性质。 在VASP赝势文件中,PAW PBE是同时使用PAW方法和PBE泛函进行计算。将PAW和PBE相结合,可以更准确地描述原子和分子体系的性质。PAW方法解决了赝波函数与真实波函数不匹配的问题,而PBE泛函考虑了交换-相关能的影响,两者的结合可以更精确地描述材料的能带结构、电荷密度分布等性质。 总而言之,VASP赝势文件PAW PBE结合了PAW方法和PBE泛函,可用于模拟材料的电子结构和性质,具有较高的准确性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值