【问题标题】:AES cipher text is different [duplicate]AES密文不同[重复]
【发布时间】:2013-02-14 23:58:19
【问题描述】:

我在 Android 和 Java servlet 环境中使用 AES 加密和充气城堡实现。加密部分在这两种情况下都可以。但是,一旦我用相同的密钥加密相同的文本,我会在这两个平台上得到不同的结果。

我的目的是在 Android 中进行加密并在 Web 环境中进行解密。

这是我为 Android AES 实现所做的唯一更改。

    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = null;
    if (android.os.Build.VERSION.SDK_INT >= JELLY_BEAN_4_2) {
        sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
    } else {
        sr = SecureRandom.getInstance("SHA1PRNG");
    }
    sr.setSeed(key);
    kgen.init(128, sr);
    SecretKey skey = kgen.generateKey();
    byte[] raw = skey.getEncoded();

上面我只是将 Crypto 添加到 get 实例中。

我也使用了 spongy castle 实现来看看我是否可以实现这一点。它仍然给了我与 Android 相同的结果。不确定我是否已正确加载它。我在 API 级别 14 和 17 上对此进行了测试。

这会导致 javax.crypto.BadPaddingException: pad block损坏。

【问题讨论】:

  • 不要使用 SecureRandom 来执行此操作。这是错误的。
  • 那我该怎么用呢?
  • 除非您发布 Android 部分的加密代码和 servlet 部分的解密代码,否则我们看不到您的错误。您提供的密钥生成代码无关紧要。
  • SecureRandom 用于生成随机数。如果您在生产代码中提供种子,那么您做错了什么。使用种子可以在测试中获得可重现的行为,但如果在您的实际加密代码中使用它,就会错过生成随机数的要点。
  • 要么直接使用key 作为 AES 密钥,要么使用专门的密钥派生函数。不要滥用 SecureRandom 作为 KDF。 HKDF 实现起来非常简单,是从主密钥派生多个密钥的绝佳选择。如果密钥实际上是密码,则需要使用基于密码的 KDF,例如 PBKDF2。

标签: java android cryptography aes bouncycastle


【解决方案1】:

对于引用此线程的任何人,这是我对代码所做的更改。现在它在 Android 和服务器环境中运行良好。

答案来自,

Android 4.2 broke my encrypt/decrypt code and the provided solutions don't work

感谢@kroot

    /* Store these things on disk used to derive key later: */
    int iterationCount = 1000;
    int saltLength = 32; // bytes; should be the same size as the output
                            // (256 / 8 = 32)
    int keyLength = 256; // 256-bits for AES-256, 128-bits for AES-128, etc
    byte[] salt = new byte[saltLength]; // Should be of saltLength

    /* When first creating the key, obtain a salt with this: */
    SecureRandom random = new SecureRandom();
    random.nextBytes(salt);

    /* Use this to derive the key from the password: */
    KeySpec keySpec = new PBEKeySpec(new String(key,
            Constants.CHAR_ENCODING).toCharArray(), key, iterationCount,
            keyLength);
    SecretKeyFactory keyFactory = SecretKeyFactory
            .getInstance("PBEWithSHA256And256BitAES-CBC-BC");
    byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
    SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");

    return secretKey.getEncoded();

【讨论】:

    猜你喜欢
    • 2010-12-29
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 2018-11-28
    • 2012-12-30
    • 1970-01-01
    • 2018-02-10
    • 2021-04-24
    相关资源
    最近更新 更多