Decrypt AES encrypted file in java

2019-03-16 22:21发布

问题:

I have a file encrypted with java application using AES. I also have a key file was encrypted with. But i can't understand how to use the key to decrypt file. Most tutorials and examples create temporary random key, encrypt file and decrypt it in one place. So, question is how to specify a key which have to be used for decryption?

EDIT: Samples i found use following code to generate key. I have no idea where i can use my key here.

KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey key = kgen.generateKey();

回答1:

Just to summarise my comments to Lucifer's answer.

  1. If you don't know what padding was used to encrypt, then decrypt with 'no padding' set. That will decrypt everything, including the padding, and won't throw an error because of mismatched padding.

  2. When you have decrypted the cyphertext, have a look at the last block of the output and see what padding was used. Different paddings leave different byte patterns, so it is usually easy enough to tell.

  3. Set your decryption method to expect the correct type of padding, and it will be automatically removed for you.



回答2:

The answer could be simply to put the key data as bytes into a SecretKeySpec like this:

SecretKeySpec aesKey = new SecretKeySpec(myKeyData, "AES");

Note that SecretKeySpec implements the Key interface, so you can use it directly in a Cipher.init() method. So there is no SecretKeyFactory needed, which you would use otherwise.



回答3:

Please try following methods, if might helpful for you.

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
        throws Exception
{
    int minSize = cipher.getOutputSize(data.length);
    byte[] outBuf = new byte[minSize];
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
    int length2 = cipher.doFinal(outBuf, length1);
    int actualLength = length1 + length2;
    byte[] result = new byte[actualLength];
    System.arraycopy(outBuf, 0, result, 0, result.length);
    return result;
}

private static byte[] decrypt(byte[] cipher, byte[] key, byte[] iv) throws Exception
{
    PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
            new AESEngine()));
    CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
    aes.init(false, ivAndKey);
    return cipherData(aes, cipher);
}

private static byte[] encrypt(byte[] plain, byte[] key, byte[] iv) throws Exception
{
    PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
            new AESEngine()));
    CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
    aes.init(true, ivAndKey);
    return cipherData(aes, plain);
}


回答4:

Complete example of encrypting/Decrypting a huge video without throwing Java OutOfMemoryException and using Java SecureRandom for Initialization Vector generation. Also depicted storing key bytes to database and then reconstructing same key from those bytes.

https://stackoverflow.com/a/18892960/185022