我是安全方面的新手,我想知道我是否可以让我的程序变得更好,例如更改或添加一些东西以使其更好(更安全)
(我对程序输出有疑问)
这是输出:
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如果没有身份验证,您将面临无法检测到(恶意)密文修改的威胁。最好对您的密文进行身份验证,以便像 padding oracle attack 这样的攻击不可能。这可以通过 GCM 或 EAX 等身份验证模式或使用 encrypt-then-MAC 来完成。通过具有强大哈希函数(例如 SHA-256)的 HMAC 方案。
由于这些问题,您应该改用库。尝试 JNCryptor或 this library .
关于java - 这是 Java 中最好/安全的加密方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43101699/