Android:使用带有iv和密钥的AES 256位加密来加密字符串

SecureRandom random = new SecureRandom(); // quite heavy, look into a lighter method. String stringToEncrypt = "mypassword"; byte[] realiv = new byte[16]; random.nextBytes(realiv); Cipher ecipher = Cipher.getInstance("AES"); SecureRandom random = new SecureRandom(); // quite heavy, look into a lighter method. byte[] realiv = new byte[16]; random.nextBytes(realiv); byte[] secret = "somelongsecretkey".getBytes(); SecretKeySpec secretKey = new SecretKeySpec(secret, "AES"); ecipher.init(Cipher.ENCRYPT_MODE, secretKey, random); byte[] encryptedData = ecipher.doFinal(); 

init()只接受3个参数。 我需要一种方法来做类似的事情:

 ecipher.init(Cipher.ENCRYPT_MODE, stringToEncrypt, secretKey, random); 

通常,您不需要为具有确定性行为的算法生成随机数的东西。 此外,当您使用ECB块模式时,您不需要IV,这是Java默认的模式。 确切地说,Java默认为Cipher.getInstance("AES") "AES/ECB/PKCS5Padding"

所以你应该可以使用这样的代码:

 // lets use the actual key value instead of the platform specific character decoding byte[] secret = Hex.decodeHex("25d6c7fe35b9979a161f2136cd13b0ff".toCharArray()); // that's fine SecretKeySpec secretKey = new SecretKeySpec(secret, "AES"); // SecureRandom should either be slow or be implemented in hardware SecureRandom random = new SecureRandom(); // first create the cipher Cipher eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // filled with 00h characters first, use Cipher instance so you can switch algorithms byte[] realIV = new byte[eCipher.getBlockSize()]; // actually fill with random random.nextBytes(realIV); // MISSING: create IvParameterSpec IvParameterSpec ivSpec = new IvParameterSpec(realIV); // create the cipher using the IV eCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec); // NOTE: you should really not encrypt passwords for verification String stringToEncrypt = "mypassword"; // convert to bytes first, but don't use the platform encoding byte[] dataToEncrypt = stringToEncrypt.getBytes(Charset.forName("UTF-8")); // actually do the encryption using the data byte[] encryptedData = eCipher.doFinal(dataToEncrypt); 

现在看起来好多了。 我已经使用Apache commons编解码器来解码hex字符串。

请注意,您需要使用encryptedData保存realIV ,并且您没有包含完整性保护,例如MAC(对于密码,您可能不需要它)。

我强烈怀疑你想要做的是调用ecipher.doFinal(stringToEncrypt) ,如果你有更长的字符串,可能会在一系列doUpdate(...)之后调用。

.init()创建密码对象, update()doFinal()填充加密输出并将明文作为输入。

当然,您需要在String和字节数组之间进行转换 。