java - 这是 Java 中最好/安全的加密方法吗?

标签 java security aes

我是安全方面的新手,我想知道我是否可以让我的程序变得更好,例如更改或添加一些东西以使其更好(更安全)
(我对程序输出有疑问)

这是输出:

Encrypted Message: +g@þóv«5Ùû`ž   
keybyte: [B@71e7a66b   
Original string: Message   
Original string (Hex): [B@2ac1fdc4

代码如下:

public class AES {

  public static void main(String ... args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
    final String Algo="AES";
    String key = "aaaaaaaaaaaaaaaa";
    byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);

    MessageDigest sha= MessageDigest.getInstance("SHA-1"); 
    keyBytes=sha.digest(keyBytes);
    keyBytes=Arrays.copyOf(keyBytes, 16);

    SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, Algo);
    Cipher cipher = Cipher.getInstance(Algo);
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
    byte[] ciphertext = cipher.doFinal("Message".getBytes());
    System.out.println("Encrypted Message: " +new String(ciphertext));

    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
    byte[] original = cipher.doFinal(ciphertext);
    String originalString = new String(original);
    System.out.println("keybyte: "+keyBytes);
    System.out.println("Original string: " + originalString + "\nOriginal string (Hex): " +original);      
  }
}

最佳答案

不,这段代码很糟糕:

  • 您的 key 是固定的,然后是一个经过哈希处理的字符串。在我看来,您的 key 实际上应该是密码。单个散列不足以从密码派生 key 。您需要使用强大的哈希方案,如 PBKDF2、bcrypt、scrypt 和 Argon2。请务必使用高成本因素/迭代次数。通常选择成本以使单次迭代至少花费 100 毫秒。查看更多:How to securely hash passwords?

  • 始终使用完全限定的密码字符串。 Cipher.getInstance("AES"); 可能会产生不同的密码,具体取决于默认的安全提供程序。它很可能导致 "AES/ECB/PKCS5Padding",但不一定是。如果它发生变化,您将失去不同 JVM 之间的兼容性。供引用:Java default Crypto/AES behavior

  • ECB mode很糟糕。它是确定性的,因此在语义上不安全。您至少应该使用像 CBC 这样的随机模式。或 CTR .

  • 如果没有身份验证,您将面临无法检测到(恶意)密文修改的威胁。最好对您的密文进行身份验证,以便像 padding oracle attack 这样的攻击不可能。这可以通过 GCM 或 EAX 等身份验证模式或使用 encrypt-then-MAC 来完成。通过具有强大哈希函数(例如 SHA-256)的 HMAC 方案。

由于这些问题,您应该改用库。尝试 JNCryptorthis library .

关于java - 这是 Java 中最好/安全的加密方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43101699/

相关文章:

encryption - 当 AesManaged.FeedbackSize = 128 时,为什么 AesManaged.FeedbackSizeValue = 8

java - 行选择在 JTable 中不起作用

java - AES 文件加密/解密

java - 用户从应用程序登录数据库

php - 在哪里使用 mysql_real_escape_string 来防止 SQL 注入(inject)?

security - 带有 API 的 TrueCrypt 替代方案

security - http和https的区别

javascript - CryptoJS 加密所需的 JS 库

java - CMN0420E Websphere Commerce 错误

java - 在文件中写入和读取整数和字符串