解释以了解AES加密代码

时间:2014-01-06 11:50:32

标签: java encryption cryptography aes jce

我正在创建一个加密和解密文件的项目。我有这两种算法可以正常工作:

public static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {

    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(clear);
    return encrypted;
}

public static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {

    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] decrypted = cipher.doFinal(encrypted);
    return decrypted;
}

public static byte[] getRaw(String password_) throws Exception {

    byte[] keyStart = password_.getBytes();
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
    sr.setSeed(keyStart);
    kgen.init(128, sr); 
    SecretKey skey = kgen.generateKey();
    byte[] key = skey.getEncoded();  

    return key;
}

现在我需要解释它是如何工作的。它使用私钥吗?密钥存储在哪里?任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

  

注意:请参阅owlstead's answer以获取代码示例中漏洞的精彩描述

您的encrypt()decrypt()操作分别使用Java AES执行JCE libraries加密和解密。将选择JCE提供程序来执行实际的加密 - 选择的提供程序将是list of providers中提供AES实现的第一个提供程序。您已将算法定义为“AES”,因此提供程序将选择操作模式和填充。如果您想对此进行控制,请使用"AES/mode/padding"表单(有关有效选择,请参阅the docs

getRaw方法从密码派生AES密钥。密码的原始字节为随机数生成器提供the seed。然后使用随机数生成器为128位AES密钥生成足够的密钥材料。不同的密码将产生不同的种子,这应该产生不同的随机字节流,从而产生不同的密钥。我怀疑大多数人的密码缺少熵会削弱这种方法,导致key space次攻击减少。

示例代码中没有密钥存储空间。 JCE密钥通常使用KeyStore对象持久存储,存储机制依赖于提供程序。

答案 1 :(得分:2)

上面的代码是一堆垃圾。不幸的是,它经常被用作Android相关代码的代码片段(Android代码使用与Java相同的API,因此不需要Android特定的示例,不幸的是它在Android 上特别失败)。

我会解释这些问题:

  1. 使用SecureRandom作为基于密码的密钥派生函数(PBKDF)是完全愚蠢的。 SecureRandom实现的底层实现可能会发生变化。此外,调用SecureRandom的{​​{1}}未指定,因为第一种方法将替换种子;它实际上可以种子添加到当前状态 - 这就是某些较新的 Android版本所做的事情。
  2. setSeed()实际上使用提供程序默认值,而不是为给定的密码指定操作模式和填充模式。默认情况下,Sun提供商将使用ECB模式,该模式不适合加密大多数数据。
  3. Cipher.getInstance("AES") - 用于密码 - 返回平台默认编码。不同的平台可能具有不同的默认编码。这意味着不同的平台将生成不同的密钥。
  4. 以上代码不添加消息验证码(MAC或HMAC)。这可能导致攻击者更改随机密文块,从而导致随机纯文本块。如果适用填充Oracle攻击,这可能会导致机密性丢失。
  5. 在我看来,你是密码学的初学者。请使用更高级别的标准,例如RNCryptor compatible code,或使用Cryptographic Message Syntax (CMS)等标准。