java AES使用相同的IV进行加密和解密
我的代码有一些问题,我没有使用相同的IV进行加密和解密。我知道,为了正确地执行此操作,我必须在输入数据之前将IV写入我的输出文件,但是我正在努力实现这一点。有人能帮我解决这个问题吗
再次编辑代码以显示全部范围
public class TestFileEncryption {
private static void mainCrypto(int cipherMode, File inputFile, File outputFile) throws Exception{
//Let the user enter the key they wish to use
Key secretKey = new SecretKeySpec(UITest.getStoreKey().getBytes(), UITest.getSendAlg()); //Generates a key based on the default keysize for the specified algorithm
//Generate an Initialization Vector (IV)
final int ALG_KEYLENGTH = UITest.getStoreKey().length(); //Change this as desired for the security level you want
byte[] iv = new byte[ALG_KEYLENGTH]; //Save the IV bytes or send it in plaintext with the encrypted data so you can decrypt the data later
SecureRandom prng = new SecureRandom(); //Use SecureRandom to generate random bits. The size of the IV matches the blocksize of the cipher
prng.nextBytes(iv); //Construct the appropriate IvParameterSpec object for the data to pass to Cipher's init() method
//Create a Cipher by specifying the following parameters: Alg name, Mode (CBC), Padding (PKC7/PKCS5)
Cipher cipherForEncryption = Cipher.getInstance(UITest.getSendAlg() + "/CBC/PKCS5PADDING"); // Must specify the mode explicitly as most JCE providers default to ECB mode
//Initialize the Cipher for Encryption
cipherForEncryption.init(cipherMode, secretKey, new IvParameterSpec(iv));
//Declare / Initialize the Data, Convert the Input to Bytes and encrypt or decrypt using doFinal.
FileInputStream inputStream = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int) inputFile.length() - ALG_KEYLENGTH];
inputStream.read(iv);
inputStream.read(inputBytes);
byte[] outputBytes = cipherForEncryption.doFinal(inputBytes);
FileOutputStream outputStream = new FileOutputStream(outputFile);
outputStream.write(iv);
outputStream.write(outputBytes);
inputStream.close();
outputStream.close();
}
public static void encrypt(File inputFile, File outputFile) throws Exception {
mainCrypto(Cipher.ENCRYPT_MODE, inputFile, outputFile); //ENC_MODE = Constant used to initialize cipher to encryption mode.
}
public static void decrypt(File inputFile, File outputFile) throws Exception {
mainCrypto(Cipher.DECRYPT_MODE, inputFile, outputFile); //ENC_MODE = Constant used to initialize cipher to encryption mode.
}
public static void main(String[] args) {}
}
# 1 楼答案
只是扩展了@Javier的答案
看起来您希望使用相同的方法进行加密和解密(取决于模式),但是在处理IV时存在差异
您生成了一个随机IV,然后使用(普通)输入的输入对其进行重写,最后将其写入输出(不管它是如何解密的)
因此,您必须区分模式是否为
诸如此类:
为了省去一些细节,也许您可以直接使用Java CipherOutputStream和CipherInputStream,实现将为您处理这些细节(如果您不关心确切的格式)
接下来您缺少的是一个身份验证标记,至少是确保密文完整性的明文散列。(称为身份验证加密)
# 2 楼答案
你只需要在密文之前写IV:
然后,解密时,读取IV和密文:
这里
ALG_BLOCKSIZE
对于AES-CBC需要为16