Java AES 并使用我自己的密钥 [英] Java AES and using my own Key

查看:35
本文介绍了Java AES 并使用我自己的密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用我自己的密钥使用 AES 加密一个字符串.但是我对密钥的位长有问题.您能否查看我的代码并查看我需要修复/更改的内容.

I want to encrypt a string using AES with my own key. But I'm having trouble with the bit length of the key. Can you review my code and see what I need to fix/change.

public static void main(String[] args) throws Exception {
    String username = "bob@google.org";
    String password = "Password1";
    String secretID = "BlahBlahBlah";
    String SALT2 = "deliciously salty";

    // Get the Key
    byte[] key = (SALT2 + username + password).getBytes();
    System.out.println((SALT2 + username + password).getBytes().length);

    // Need to pad key for AES
    // TODO: Best way?

    // Generate the secret key specs.
    SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

    // Instantiate the cipher
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

    byte[] encrypted = cipher.doFinal((secrectID).getBytes());
    System.out.println("encrypted string: " + asHex(encrypted));

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

现在我收到一个异常无效的 AES 密钥长度:86 字节".我需要垫我的钥匙吗?我该怎么做?

Right now I get an exception "Invalid AES key length: 86 bytes". Do I need to pad my key? How should I do it?

我还需要为 ECB 或 CBC 设置什么吗?

Also do I need to set anything for ECB or CBC?

谢谢

推荐答案

正如评论中所写,旧代码不是最佳实践".您应该使用具有高迭代次数的密钥生成算法,例如 PBKDF2.您还应该至少部分使用非静态(意味着每个身份"专有)盐.如果可能,随机生成并与密文存储在一起.

As written in the comments the old code is not "best practice". You should use a keygeneration algorithm like PBKDF2 with a high iteration count. You also should use at least partly a non static (meaning for each "identity" exclusive) salt. If possible randomly generated and stored together with the ciphertext.

    SecureRandom sr = SecureRandom.getInstanceStrong();
    byte[] salt = new byte[16];
    sr.nextBytes(salt);

    PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 1000, 128 * 8);
    SecretKey key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(spec);
    Cipher aes = Cipher.getInstance("AES");
    aes.init(Cipher.ENCRYPT_MODE, key);

============

===========

您应该使用 SHA-1 从您的密钥生成一个散列并将结果修剪为 128 位(16 字节).

You should use SHA-1 to generate a hash from your key and trim the result to 128 bit (16 bytes).

另外不要通过getBytes()从字符串生成字节数组,它使用平台默认字符集.所以密码blaöä"在不同平台上导致不同的字节数组.

Additionally don't generate byte arrays from Strings through getBytes() it uses the platform default Charset. So the password "blaöä" results in different byte array on different platforms.

byte[] key = (SALT2 + username + password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit

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

如果您需要 256 位作为密钥大小,您需要下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files"Oracle 下载链接,使用 SHA-256 作为哈希值并删除 Arrays.copyOf 行.ECB"是默认密码模式,PKCS5Padding"是默认填充.您可以使用以下格式通过 Cipher.getInstance 字符串使用不同的密码模式和填充模式:密码/模式/填充"

If you need 256 bit as key sizes you need to download the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" Oracle download link, use SHA-256 as hash and remove the Arrays.copyOf line. "ECB" is the default Cipher Mode and "PKCS5Padding" the default padding. You could use different Cipher Modes and Padding Modes through the Cipher.getInstance string using following format: "Cipher/Mode/Padding"

对于使用 CTS 和 PKCS5Padding 的 AES,字符串为:"AES/CTS/PKCS5Padding"

For AES using CTS and PKCS5Padding the string is: "AES/CTS/PKCS5Padding"

这篇关于Java AES 并使用我自己的密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆