如果我用随机密钥加密字符串,如何解密它

Posted

技术标签:

【中文标题】如果我用随机密钥加密字符串,如何解密它【英文标题】:How can I decrypt a string if I encrypt it with a random key 【发布时间】:2021-11-01 05:01:58 【问题描述】:

我正在尝试用 java 开发一个需要加密的 android 应用程序。我也想使用 AES-256 进行加密。但是当我看它的教程时,它总是会生成一个随机密钥。我的问题是:?此外,我几乎尝试了 web 中的所有代码,但没有一个有效,所以你能提供一个没有盐和 IV 的 AES-256 加密代码。如果我知道错了,请纠正我并教我真相。

编辑:我正在尝试制作密码管理器应用程序。 App有两个密码,第一个是我们用于加密字符串数据的主密码。第二个是我们要管理的密码。主密码存储在用户心中。其他密码将以加密版本存储在应用程序中。 当用户想要查看他的密码时,他将输入他的主密钥来解密加密的密码。那么我该怎么做呢?用户的主密码将是 32 位或 64 位,我认为我们不需要生成随机密钥。你能告诉我一些方法吗?我不是以英语为母语的人,抱歉我的英语不好。感谢您的帮助。

【问题讨论】:

加密很容易——密钥管理很难。如果您无法安全地管理密钥,加密将毫无用处。如何做到这一点取决于您想要实现的目标。 “app ...需要加密”太笼统了。更好地描述您想要实现的目标。 “我几乎尝试了 web 中的所有代码,但没有一个有效”:这种方法可能适用于用户界面。但是为了安全,这是灾难的秘诀。请自学基本的安全概念。 您到底想做什么?你只是想加密一个简单的消息并存储它吗?您是否尝试在应用程序和服务器之间进行双向加密?如果您不确切知道自己在做什么以及为什么要驯服,加密可能是一头讨厌的野兽。 如果您的应用需要安全地存储(用户)数据,我建议使用“EncryptedSharedPreferences”:developer.android.com/topic/security/data。请编辑您的问题并更好地描述您的应用需要加密的功能。 我支持上面所有的 cmets。 “如果我用随机密钥加密字符串,如何解密字符串?”的答案是:你需要钥匙。如果您没有密钥,因为它是随机生成的并且没有存储在某个地方,您无法解密它。 【参考方案1】:

正如您已经发现的那样,随机密钥对您的应用没有意义。相反,您希望从主密码派生密钥。为此,您使用密钥派生函数KDF

为了防止字典攻击,您还必须使用盐。盐是您生成一次然后存储在您的应用程序中的随机值(没有任何加密)。

制作盐

void initSalt()

    byte[] salt = new byte[32];
    new SecureRandom().nextBytes(salt);
    
    ... save salt ...

获取加密密钥

SecretKey getSecretKey(String masterPassword)

    byte[] salt = ... retrieve saved salt ...

    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
    char[] chars = password.toCharArray();
    int hashIterations = 1024;
    int keySizeBytes = 32;
    return keyFactory.generateSecret(
        new PBEKeySpec(chars, salt, hashIterations, keySizeBytes * 8));

getSecretKey() 函数在首次设置密码管理器时以及以后使用时都会调用。如果盐没有改变,该函数将始终返回相同的密钥。

某些 Android 版本可能不支持 PBKDF2WithHmacSHA256。如果是这样,您必须恢复为 PBKDF2withHmacSHA1

使用从主密码生成的密钥,您可以继续对密码管理器要存储的数据进行加密。

【讨论】:

以上是关于如果我用随机密钥加密字符串,如何解密它的主要内容,如果未能解决你的问题,请参考以下文章

如何实现用javascript实现rsa加解密

为啥我用Base64加密后,不能将它解密?

在Java中生成和使用两个密钥进行加密和解密

如何在python中加密JSON

Https 密钥协商中的第三个随机数pre-master-key如何防篡改?

AES加密和解密Java