我正在尝试在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);