Java 在openssl中解密文本文件:-错误:EVP_DecryptFinal_ex:错误的最终块长度:EVP_enc.c:518:

Java 在openssl中解密文本文件:-错误:EVP_DecryptFinal_ex:错误的最终块长度:EVP_enc.c:518:,java,android,encryption,openssl,Java,Android,Encryption,Openssl,我正在编写一个小应用程序来了解更多的加密/解密。 从我的代码中,我生成AES密钥,然后用AES密钥加密文本文件。之后,我用RSA公钥加密AES密钥 下面是代码片段 SecretKey secretAesKey ; KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(256); secretAesKey = keyGen.generateKey(); if (secretAesKey != null) { C

我正在编写一个小应用程序来了解更多的加密/解密。 从我的代码中,我生成AES密钥,然后用AES密钥加密文本文件。之后,我用RSA公钥加密AES密钥

下面是代码片段

SecretKey secretAesKey ;
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
secretAesKey = keyGen.generateKey();
if (secretAesKey != null) {
    Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    aesCipher.init(Cipher.ENCRYPT_MODE, secretAesKey);
    long aesEncryptStartTime = SystemClock.elapsedRealtime();
    CipherInputStream aesCis = new CipherInputStream(fis, aesCipher);
    int read;
    byte[] buffer = new byte[4096];
    while ((read = aesCis.read(buffer)) != -1) {
        aesFos.write(buffer, 0, read);
        aesFos.flush();
    }

    // Encrypt the generated key
    if (!encKeyFile.exists()) {
        encKeyFile.createNewFile();
    }

    try {
        byte[] encryptedAesKey = null;
        Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        rsaCipher.init(Cipher.ENCRYPT_MODE, readRsaPublicKeyFromResource(context));
        encryptedAesKey = rsaCipher.doFinal(secretAesKey.getEncoded());
        rsaFos.write(encryptedAesKey);
        rsaFos.flush();
    } catch (Exception e) {
        Log.e(LOG_TAG, "RSA encryption error", e);
    } finally {
        rsaFos.close();
    }
在解密过程中,首先使用RSA私钥从以下代码中解密AES密钥

FileInputStream keyFis = new FileInputStream(encKeyFile);
byte[] encKey = new byte[keyFis.available()];
keyFis.read(encKey);
keyFis.close();

SecretKey key = null;
PrivateKey privKey = readRsaPrivateKeyFromResource(context);
Cipher cipher = null;

try
{
    // initialize the cipher...
    cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.DECRYPT_MODE, privKey);
    // generate the aes key!
    key = new SecretKeySpec (cipher.doFinal(encKey), "AES" );
    String stringKey = Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
    try {
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput("aesDecrypted.key", Context.MODE_PRIVATE));
        outputStreamWriter.write(stringKey);
        outputStreamWriter.close();
    }
    catch (IOException e) {
        Log.e("Exception", "File write failed: " + e.toString());
    }
我得到了解密的AES密钥,例如“ah3ZWMieji6KtSav6gaayTvsEID2vpp589wdChTLmZs=”

将其转换为十六进制值后,如下所示。“6A1DD958C89E8E2E8AB526AFEA069AC93BEC1080F6BE9A79F3DC1D0A14CB999B”

试图用终端中生成的十六进制密钥解密文本文件 例如:

openssl aes-256-cbc-d-a-iv 0-in encrypt.txt-out decrypt.txt-K 6A1DD958C89E8E2E8AB526AFEA069AC93BEC1080F6BE9A79F3DC1D0A14CB999B

我得到以下错误

解密错误 7560:错误:0606506D:数字信封例程:EVP_DecryptFinal_ex:错误的最终块长度:EVP_enc.c:518:

为什么会这样,更进一步,我做错了什么


如果有人能帮忙,我将非常感谢。

您的代码有多个问题,下面是一个非详尽的列表:

  • Java自动为您生成一个随机IV,但您忘记保存它以进行解密(
    cipher.getParameters().getParameterSpec(IvParameterSpec.class)))。静脉注射不是秘密。通常,它与密文一起发送

  • 使用
    keyFis.available()
    是个坏主意,因为流不会告诉您底层文件有多大,而是告诉您其内部缓冲区中还有多少字节。使用不同的技术获取文件的大小

  • 您已尝试实现混合加密。解密时,您需要反转过程:首先使用RSA解密AES密钥,然后使用AES解密实际数据


我已尝试使用以下语句字符串stringKey=Base64.encodeToString(secretAesKey.getEncoded(),Base64.DEFAULT)检查生成的密钥;这和我解密AES密钥后得到的相同。你能详细说明一下如何保存随机IV密钥吗?我做了:
aesciper.getParameters().getParameterSpec(IvParameterSpec.class)).getIV()我尝试在openssl命令中添加IV密钥:-“openssl aes-256-cbc-d-a-IV 0037AC1DA2C0CE1C66AC3BF88D39ED92-in encrypt.txt-out final.txt-K F60824222EC05FA3DC25E3FE6349401FE6897581A99CF43A64864B641D7C98”解密错误2780:错误:0606506D:数字信封例程:EVP_DecryptFinal_ex:错误的最终块长度:EVP_enc.c:518:仍然不走运。@openssl中的暂停选项
-a
表示文件位于base64中。。但是您的AES加密文件不在base64中。。