加密或哈希

huangapple go评论82阅读模式
英文:

Encryption or hashing

问题

我找到一个在线函数,它声称这是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);
         
        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("加密时出错:" + e.toString());
    }
    return null;
}

现在,这里使用了HMAC-SHA256。那么这实际上是AES,还是哈希?还是仅使用HMAC对秘钥进行哈希?我的意思是SHA-256是一个哈希算法吗?
另外,这可能听起来非常基础,但HMAC是哈希/加密吗?

英文:

I got one function online saying this is AES-256 bit encryption:

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;
}

Now, this is using HMAC-SHA256. So is this actually AES or is this hashing? Or is it only hashing the secret key using HMAC? I mean SHA-256 is a hashing algorithm?
Also, it might sound very basic but Is HMAC a hashing/encryption?

答案1

得分: 4

这里使用PKBDF2将密码延展为一个密钥。然后使用该密钥以CBC模式对数据进行AES加密。

PBKDF2需要一个伪随机函数(PRF),这里使用的PRF是HMAC。HMAC需要一个压缩(哈希)函数,该函数是SHA-2,具有256位摘要大小(通常称为"SHA-256")。

我不会说"这是AES-256位加密"。这是一个完整的加密系统,其中包括AES-256作为其组件之一。有许多其他(更安全)的方法可以使用AES进行加密。例如,假设saltsecret是恒定的,这似乎具有静态IV +密钥。这是一种使用CBC模式的不安全方式。它也缺乏任何形式的认证,因此消息在传输过程中有可能被修改。这些缺陷很常见,但是这不应该被视为AES-256的典型示例。

英文:

This is using PKBDF2 to stretch a password into a key. It's then using that key to encrypt the data with AES in CBC mode.

PBKDF2 requires a pseudorandom function (PRF), and the PRF used here is HMAC. HMAC requires a compression (hash) function, and that function is SHA-2, with a 256-bit digest size (commonly called "SHA-256").

I wouldn't say "this is AES-256 bit encryption." This is a complete crypto system that includes AES-256 as one of its components. There are many other (and more secure) ways to encrypt things using AES. For example, this appears to have a static IV+Key (assuming that salt and secret are constant). That's an insecure way to use CBC mode. It also lacks any kind of authentication, so messages can potentially be modified in transit. Those kinds of flaws are common, but this shouldn't be thought of as a canonical example of AES-256.

答案2

得分: 1

我将代码分为几个部分:

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")));

这就是加密本身。因此,整个示例是为了提供加密。哈希仅用作“伸缩密钥”算法的一部分 - 从密码创建加密密钥。

此示例不提供任何身份验证 - 密文可能会被篡改,您无法验证完整性。

英文:

I'd separate the code to several parts:

    byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    IvParameterSpec ivspec = new IvParameterSpec(iv);

NEVER EVER use static IV while reusing the same key. Using the same IV and key for encryption can (and in many instances will) provide ways to reveal some data or completely break the encryption. The IV is intended to make safe to reuse the same encryption key, for the CBC mode the IV needs to be more than random, it must be unpredictable.

Using a static IV is a common error when copy/paste code without deeper understanding.

    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");

An encryption key needs to have a specific length (AES-256 needs 256 bit ) and a key is expected to have high entropy (high randomness).

Human passwords are tend to have different length and the passwords are having much less randomness. This piece of code (as already described in another answer) creates a key from a password using 65536 rounds containing the SHA-256 hashing.

Multiple rounds are used to slow down the key generation, trying to make brute forcing less viable.

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
    return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));

This is encryption itself. So the whole example is to provide the encryption. The hashing is only used as a part of the "key stretching" algorithm - creating an encryption key from a password.

This example doesn't provide any authentication -the ciphertext could be tampered with and you have no means to validate the integrity.

答案3

得分: 0

不要使用这段代码,它不安全。它基于我的一个回答, 但在这个过程中,关键元素被改变,破坏了其完整性。

好的,让我们再试一次。

> 现在,这是使用HMAC-SHA256。

不,这是使用PBKDF2。PBKDF2反过来可以使用HMAC,而HMAC可以使用SHA-256。

PBKDF2是一个密钥派生算法。它将文本密码转换为实际与对称密码一起使用的密钥。它的设计部分是为了限制不同密码作为密钥被测试的速率。它防止了字典攻击。

> 那么这实际上是AES还是哈希?

两者都是,也都不是。这是一个基于密码的加密系统,它使用密码和密钥派生算法。正如前面提到的,这个密钥派生使用了一些算法,包括一个哈希算法。

> 或者它只是在使用HMAC对秘密密钥进行哈希?

它不仅仅是对秘密进行哈希。HMAC使用了一个哈希算法,但它还为密钥、消息以及哈希如何链接在一起指定了填充。您可以阅读更多信息。 HMAC只是作为PBKDF2的伪随机函数(PRF)的一部分,它还添加了其他元素,如对PRF与密钥的迭代、盐和计数器,以便在需要可调节的计算工作量的同时保持密钥的熵。您也可以阅读更多信息。

> 我的意思是SHA-256是一个哈希算法?

是的。但它不是在这里直接用于顶层。它是在顶层PBKDF2算法中深层嵌套的一个组件。

> 还有,这可能听起来非常基础,但HMAC是哈希/加密吗?

不是。从根本上讲,它是一个消息认证码。它可以用于检测数据的篡改。但在这里,它被用作PRF,以生成一个无法被没有密钥的人预测的数据流。

英文:

Don't use this code; it's not secure. It is based on one of my answers, but in the process, critical elements were changed that destroy its integrity.

Okay, let's try this again.

> Now, this is using HMAC-SHA256.

No, it's using PBKDF2. PBKDF2 in turn can use HMAC, and that, in turn, can use SHA-256.

PBKDF2 is a key derivation algorithm. It turns a text password into the actual key that is used with a symmetric cipher. It's designed in part to limit the rate at which different passwords can be tested as keys. It defeats dictionary attacks.

> So is this actually AES or is this Hashing?

Both. Neither. It's a password-based encryption system that uses a cipher and a key derivation algorithm. As noted already, this key derivation uses a couple of algorithms, including a hash algorithm.

> Or is it only hashing the secret key using HMAC?

It's not only hashing the secret. HMAC uses a hash algorithm, but it also specifies padding for the secret, the message, and how hashes are chained together. You can read more about it. The HMAC just acts as pseudo-random function (PRF) as part of PBKDF2, which adds other elements like iteration of the PRF with the secret, a salt, and a counter, in an effort to preserve the entropy of the secret while requiring a tunable amount of computational effort. You can read more about it too.

> I mean SHA-256 is a hashing algorithm?

Yes. But it's not used directly at a top-level here. It's a component nested deeply in a top-level PBKDF2 algorithm.

> Also, it might sound very basic but Is HMAC a hashing/encryption?

No. Fundamentally, it's a message authentication code. It can be used to detect alteration of data. But here, it's used as a PRF to generate a stream of data that can't be predicted by anyone without the secret.

huangapple
  • 本文由 发表于 2020年10月15日 03:00:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/64359897.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定