Java 加密或散列
我在网上看到一个函数说这是AES-256位加密:Java 加密或散列,java,encryption,aes,Java,Encryption,Aes,我在网上看到一个函数说这是AES-256位加密: public static String encrypt(String strToEncrypt, String secret) { try { byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; IvParameterSpec ivspec = new IvParameterSpec(iv);
public static String encrypt(String strToEncrypt, String secret)
{
try
{
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
}
catch (Exception e)
{
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
现在,这是使用HMAC-SHA256。这实际上是AES还是散列?或者只是使用HMAC对密钥进行散列?我是说SHA-256是散列算法?
此外,它听起来可能非常基本,但HMAC是哈希/加密吗?这是用来将密码扩展到密钥的。然后使用该密钥在CBC模式下用AES加密数据
PBKDF2需要一个伪随机函数(PRF),这里使用的PRF是。HMAC需要一个压缩(哈希)函数,该函数的大小为256位摘要(通常称为“SHA-256”)
我不会说“这是AES-256位加密”。这是一个完整的加密系统,其中包括AES-256作为其组件之一。还有许多其他(而且更安全)的方法可以使用AES加密内容。例如,这似乎有一个静态IV+密钥(假设
salt
和secret
是常量)。使用CBC模式是不安全的。它还缺少任何类型的身份验证,因此消息可能会在传输过程中被修改。这些类型的缺陷很常见,但不应将其视为AES-256的典型示例。我将代码分为几个部分:
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
在重复使用同一密钥时,切勿使用静态IV。使用相同的IV和密钥进行加密可以(并且在许多情况下会)提供泄露某些数据或完全破坏加密的方法。IV旨在确保安全地重复使用相同的加密密钥,对于CBC模式,IV需要的不仅仅是随机的,它必须是不可预测的
在没有深入理解的情况下复制/粘贴代码时,使用静态IV是常见的错误
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
加密密钥需要具有特定长度(AES-256需要256位),并且密钥需要具有高熵(高随机性)
人工密码往往具有不同的长度,而且密码的随机性也要小得多。这段代码(如另一个答案中所述)使用包含SHA-256哈希的65536轮密码创建密钥
使用多轮来减缓密钥生成的速度,试图降低暴力强制的可行性
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
这就是加密本身。所以整个例子就是提供加密。散列仅用作“密钥拉伸”算法的一部分,即从密码创建加密密钥
此示例不提供任何身份验证-密文可能被篡改,您无法验证完整性。不要使用此代码;它不安全。但在这个过程中,关键要素发生了变化,破坏了其完整性 好的,让我们再试一次 现在,这是使用HMAC-SHA256 不,它使用的是PBKDF2。PBKDF2反过来可以使用HMAC,而HMAC反过来可以使用SHA-256 PBKDF2是一种密钥派生算法。它将文本密码转换为与对称密码一起使用的实际密钥。它的设计部分是为了限制不同密码作为密钥进行测试的速率。它可以击败字典攻击 这实际上是AES还是散列 两者都有。也不这是一个基于密码的加密系统,使用密码和密钥派生算法。如前所述,该密钥派生使用了两种算法,包括哈希算法 或者只是使用HMAC对密钥进行散列 这不仅仅是散播秘密。HMAC使用散列算法,但它也指定秘密、消息的填充,以及散列如何链接在一起。你可以考虑一下。HMAC只是充当伪随机函数(PRF)作为PBKDF2的一部分,它添加了其他元素,如PRF与秘密、盐和计数器的迭代,以在需要可调计算量的同时保持秘密的熵。你也可以 我是说SHA-256是散列算法 对。但它并没有直接用于顶级。它是一个嵌套在顶级PBKDF2算法中的组件 此外,它可能听起来很基本,但HMAC是哈希/加密吗
不。基本上,这是一个消息身份验证码。它可用于检测数据的更改。但是在这里,它被用作PRF来生成没有秘密的任何人都无法预测的数据流。安全警告-此代码使用的是静态IV,使得完整的加密不安全。请使用随机IV和GCM模式进行身份验证。这是我对基于密码的加密问题的答案的损坏副本。那里的评论应该回答你的问题,恢复安全性所需的部分,解释更好模式的选项,等等。你的问题没有多大意义。AES提供机密性,SHA-256通过哈希提供密钥派生。它们一起构成了一个密码系统。除了密钥派生之外,还可以使用HMAC-SHA-256通过构建流式密码进行加密(保密),也可以通过使用CMAC使用AES进行真实性验证。然后他们会组成一个不同的密码系统。我有一些。还有用于密文认证(完整性检查)的HMAC,还有一个合成初始化向量(SIV)模式@kelalaka oh,它已经在RFC(rfc8452)中了:)很好,供参考