java中的Rfc2898DeriveBytes

我试图在java中实现以下代码:

var keyGenerator = new Rfc2898DeriveBytes(password, salt, 1000); byte[] key = keyGenerator.GetBytes(32); byte[] iv = keyGenerator.GetBytes(16); using (AesManaged aes = new AesManaged()) { using (ICryptoTransform encryptor = aes.CreateEncryptor(key, iv)) { byte[] result = encryptor.TransformFinalBlock(content, 0, content.Length); } } 

使用以下一个:

 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec keyspec = new PBEKeySpec(password, salt, 1000, 256); Key key = factory.generateSecret(keyspec); SecretKeySpec secret = new SecretKeySpec(key.getEncoded(), "AES"); byte[] iv = "how_to_generate_in_java_as_in_c".getBytes(); AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret, ivSpec); byte[] result = cipher.doFinal("asdfasdf".getBytes("UTF-8")); 

我查看了很多SO的例子和问题,但没有找到正确生成iv []的方法(与C中的值相同)。 并且似乎没有办法做到这一点,因为java允许仅将此值创建为随机(不是C中可用的伪随机)。 这是正确的吗? 有人可以帮忙解决这个问题吗?

得到了crypt专家的提示,找到了正确的解决方案:

 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec pbeKeySpec = new PBEKeySpec(password, salt, 1000, 384); Key secretKey = factory.generateSecret(pbeKeySpec); byte[] key = new byte[32]; byte[] iv = new byte[16]; System.arraycopy(secretKey.getEncoded(), 0, key, 0, 32); System.arraycopy(secretKey.getEncoded(), 32, iv, 0, 16); 

我想确保人们明白最终的代码应该是:

 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec pbeKeySpec = new PBEKeySpec(password, salt, 1000, 384); Key secretKey = factory.generateSecret(pbeKeySpec); byte[] key = new byte[32]; byte[] iv = new byte[16]; System.arraycopy(secretKey.getEncoded(), 0, key, 0, 32); System.arraycopy(secretKey.getEncoded(), 32, iv, 0, 16); SecretKeySpec secret = new SecretKeySpec(key, "AES"); AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret, ivSpec); byte[] result = cipher.doFinal("asdfasdf".getBytes("UTF-8")); 

如果你想使用new String(结果)将结果转换为字符串,那么最好使用新的String(结果,Charset),如果你不这样做,你可能会得到格式错误的字符串。

    Interesting Posts