为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

月关宝盒 2021-10-13 10:23:51
我正在尝试在 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 棒的一端,或者有人可以建议可能会发生什么?
查看完整描述

1 回答

?
Helenr

TA贡献1780条经验 获得超4个赞

您的理解是正确的,您的代码中的关键是相同的。

你不能“打印”aesKey因为SecretKeySpec没有toString()方法。所以内置函数Object.toString()会被调用,它只是打印对象在内存中地址

javax.crypto.spec.SecretKeySpec@14c7f    // <--- useless info //

您的代码只有几个问题:

  • 不要将加密字节转换为 UTF-8 字符串。可能存在在 UTF-8 中无效的组合,以及 00 字节。使用 Base64 或 Hex 编码打印加密数据。

  • 您不应该使用 ASCII 字节作为密钥,这会大大降低密钥的安全性。从密码中导出密钥,至少使用 SHA-256,但最好使用 PBKDF2 或 scrypt。

  • 使用高熵随机 IV 并将其与密文一起存储。

这是一个更新版本,证明它正在工作:

public static String encryptMessageGH(String message, String password) throws Exception {

    MessageDigest sha = MessageDigest.getInstance("SHA-256");

    byte[] key = sha.digest(password.getBytes("UTF-8"));

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

    byte[] iv = new byte[16];

    new SecureRandom().nextBytes(iv);

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

    cipher.init(Cipher.ENCRYPT_MODE, aesKey, new IvParameterSpec(iv));

    byte[] ciphertext = cipher.doFinal(message.getBytes());

    byte[] encrypted = new byte[iv.length + ciphertext.length];

    System.arraycopy(iv, 0, encrypted, 0, iv.length);

    System.arraycopy(ciphertext, 0, encrypted, iv.length, ciphertext.length);

    return Base64.getEncoder().encodeToString(encrypted);

}


public static String decryptMessageGH(String encryptedMessage, String password) throws Exception {

    MessageDigest sha = MessageDigest.getInstance("SHA-256");

    byte[] key = sha.digest(password.getBytes("UTF-8"));

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

    byte[] encrypted = Base64.getDecoder().decode(encryptedMessage);

    byte[] iv = new byte[16];

    System.arraycopy(encrypted, 0, iv, 0, iv.length);

    byte[] ciphertext = new byte[encrypted.length - iv.length];

    System.arraycopy(encrypted, iv.length, ciphertext, 0, ciphertext.length);

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

    cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(iv));

    return new String(cipher.doFinal(ciphertext), "UTF-8");

}


public static void main(String[] args) throws Exception {

    String orig = "Test message";

    String enc = encryptMessageGH(orig, "abcdef123");

    System.out.println("Encrypted: " + enc);

    String dec = decryptMessageGH(enc, "abcdef123");

    System.out.println("Decrypted: " + dec);

}

输出:


Encrypted: lcqcd9UZpjLSY9SsQ/N7kV/cpdzL3c7HQcCSiIs6p/k=

Decrypted: Test message


查看完整回答
反对 回复 2021-10-13
  • 1 回答
  • 0 关注
  • 89 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信