简体   繁体   English

在java中解密AES加密文件

[英]Decrypt AES encrypted file in java

I have a file encrypted with java application using AES. 我有一个使用AES使用java应用程序加密的文件。 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();

The answer could be simply to put the key data as bytes into a SecretKeySpec like this: 答案可能只是将关键数据作为字节放入SecretKeySpec,如下所示:

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

Note that SecretKeySpec implements the Key interface, so you can use it directly in a Cipher.init() method. 请注意, SecretKeySpec实现了Key接口,因此您可以直接在Cipher.init()方法中使用它。 So there is no SecretKeyFactory needed, which you would use otherwise. 所以不需要SecretKeyFactory,否则你会使用它。

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. 设置您的解密方法以期望正确的填充类型,它将自动为您删除。

Complete example of encrypting/Decrypting a huge video without throwing Java OutOfMemoryException and using Java SecureRandom for Initialization Vector generation. 完整的加密/解密 大型视频的示例, 不会抛出Java OutOfMemoryException并使用Java SecureRandom进行初始化向量生成。 Also depicted storing key bytes to database and then reconstructing same key from those bytes. 还描述了将密钥字节存储到数据库,然后从那些字节重建相同的密钥。

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

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM