相同的密码会导致 Java 中的不同 AES 密钥

我正在尝试在 Java 中跨两个设备实现 AES 加密的基本示例。然而,每次我们运行应用程序时,在两台设备上使用相同的密码(128 位)生成 AES 密钥会导致两台设备上的密钥不同。所以我们无法解密我们在设备之间发送的文本。


我使用的方法如下,它们是我在其他地方找到的代码的稍微修改版本:


public String encryptMessage(String message, String password) throws Exception {


    // Creating key and cipher

    SecretKeySpec aesKey = new SecretKeySpec(password.getBytes("UTF-8"), "AES");



    byte[] iv = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

    IvParameterSpec ivspec = new IvParameterSpec(iv);

    //AES cipher

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");


    // encrypt the text

    cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivspec);


    byte[] encrypted;


    encrypted = cipher.doFinal(message.getBytes());


    return new String(encrypted, "UTF-8");

}


public String decryptMessage(String encryptedMessage, String password) throws Exception {


    // Creating key and cipher

    byte[] passwordBytes = password.getBytes("UTF-8");


    SecretKeySpec aesKey = new SecretKeySpec(passwordBytes, "AES");


    byte[] iv = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

    IvParameterSpec ivspec = new IvParameterSpec(iv);

    //AES cipher

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");


    // decrypting the text

    cipher.init(Cipher.DECRYPT_MODE, aesKey, ivspec);

    String decrypted = new String(cipher.doFinal(encryptedMessage.getBytes(Charset.forName("UTF-8"))));


    //returning decrypted text

    return decrypted;

}

每次运行这段代码,打印出aesKey,都不一样。


我对 AES 和对称加密的理解是,给定相同的密码,它应该生成相同的密钥,否则它如何能够解密人工制品?我是否弄错了 AES 棒的一端,或者有人可以建议可能会发生什么?


月关宝盒
浏览 90回答 1
1回答

Helenr

您的理解是正确的,您的代码中的关键是相同的。你不能“打印”aesKey因为SecretKeySpec没有toString()方法。所以内置函数Object.toString()会被调用,它只是打印对象在内存中的地址javax.crypto.spec.SecretKeySpec@14c7f&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;<---&nbsp;useless&nbsp;info&nbsp;//您的代码只有几个问题:不要将加密字节转换为 UTF-8 字符串。可能存在在 UTF-8 中无效的组合,以及 00 字节。使用 Base64 或 Hex 编码打印加密数据。您不应该使用 ASCII 字节作为密钥,这会大大降低密钥的安全性。从密码中导出密钥,至少使用 SHA-256,但最好使用 PBKDF2 或 scrypt。使用高熵随机 IV 并将其与密文一起存储。这是一个更新版本,证明它正在工作:public static String encryptMessageGH(String message, String password) throws Exception {&nbsp; &nbsp; MessageDigest sha = MessageDigest.getInstance("SHA-256");&nbsp; &nbsp; byte[] key = sha.digest(password.getBytes("UTF-8"));&nbsp; &nbsp; SecretKeySpec aesKey = new SecretKeySpec(key, "AES");&nbsp; &nbsp; byte[] iv = new byte[16];&nbsp; &nbsp; new SecureRandom().nextBytes(iv);&nbsp; &nbsp; Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");&nbsp; &nbsp; cipher.init(Cipher.ENCRYPT_MODE, aesKey, new IvParameterSpec(iv));&nbsp; &nbsp; byte[] ciphertext = cipher.doFinal(message.getBytes());&nbsp; &nbsp; byte[] encrypted = new byte[iv.length + ciphertext.length];&nbsp; &nbsp; System.arraycopy(iv, 0, encrypted, 0, iv.length);&nbsp; &nbsp; System.arraycopy(ciphertext, 0, encrypted, iv.length, ciphertext.length);&nbsp; &nbsp; return Base64.getEncoder().encodeToString(encrypted);}public static String decryptMessageGH(String encryptedMessage, String password) throws Exception {&nbsp; &nbsp; MessageDigest sha = MessageDigest.getInstance("SHA-256");&nbsp; &nbsp; byte[] key = sha.digest(password.getBytes("UTF-8"));&nbsp; &nbsp; SecretKeySpec aesKey = new SecretKeySpec(key, "AES");&nbsp; &nbsp; byte[] encrypted = Base64.getDecoder().decode(encryptedMessage);&nbsp; &nbsp; byte[] iv = new byte[16];&nbsp; &nbsp; System.arraycopy(encrypted, 0, iv, 0, iv.length);&nbsp; &nbsp; byte[] ciphertext = new byte[encrypted.length - iv.length];&nbsp; &nbsp; System.arraycopy(encrypted, iv.length, ciphertext, 0, ciphertext.length);&nbsp; &nbsp; Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");&nbsp; &nbsp; cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(iv));&nbsp; &nbsp; return new String(cipher.doFinal(ciphertext), "UTF-8");}public static void main(String[] args) throws Exception {&nbsp; &nbsp; String orig = "Test message";&nbsp; &nbsp; String enc = encryptMessageGH(orig, "abcdef123");&nbsp; &nbsp; System.out.println("Encrypted: " + enc);&nbsp; &nbsp; String dec = decryptMessageGH(enc, "abcdef123");&nbsp; &nbsp; System.out.println("Decrypted: " + dec);}输出:Encrypted: lcqcd9UZpjLSY9SsQ/N7kV/cpdzL3c7HQcCSiIs6p/k=Decrypted: Test message
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java