Java AES 加密无法正确解密

标签 java gzip aes

我在下面进行了这个测试,我试图验证我的 AES 加密/解密和压缩/解压缩是否正常工作。我有一个仅针对加密/解密的测试和仅针对压缩/解压缩的测试,我知道它们单独工作正常,但由于某种原因,当我将它们组合起来时,IV 在解压后会搞砸。我被困住了,不知道还要寻找什么,任何人都可以提供任何建议或帮助吗?如果我需要发布更多代码,请告诉我。我想我已经包含了重要的内容。

就上下文而言:我想做的是获取一些敏感数据,使用 AES 对其进行加密,使用 RSA 公钥对 AES key 进行加密,然后压缩这两条数据,以便可以通过网络发送它们。然后在另一端我想解压缩数据,使用 RSA 私钥来解密 AES key ,然后使用它来解密数据。如果有另一种方法可以实现这一点,我就不会被困住自己写所有的东西。如果您建议一个库,请仅建议我可以在商业产品中使用的库。

@Test
public void testEncryptionDecryptionProcesses() throws SSHException {

    SSHKey key1 = generateKeyPair();

    UnencryptedData data = new UnencryptedData();
    data.setUserName("hardy");
    data.setHashedPassword("somepassword");
    data.setRequest("eat");
    data.setResponse("");
    data.setTimestamp(new Timestamp(new Date().getTime()).toString());
    data.setPublicKeyMod(key1.getPublicMod().toString());
    data.setPublicKey(key1.getPublicKey().toString());

    byte[] bytes = encryptAndCompress(data, key1);

    assertTrue(bytes != null);
    assertTrue(bytes.length > 0);

    UnencryptedData decryptedData = decompressAndDecrypt(bytes, key1);
    assertEquals(data.getDataForEncryption(), decryptedData.getDataForEncryption());

}

public static byte[] encryptAndCompress(UnencryptedData data, SSHKey sshKey) {

    byte[] results = null;

    try {
        byte[] aesKey = createKeyForAES(AES_BIT_LENGTH);
        //this should use the servers public key so that only the server can decrypt it
        //gather data, get a digest, encrypt the data
        UnencryptedData digestedData = createDigest(data);
        //encrypt it
        EncryptedData toCompress = encryptDataAES(digestedData, aesKey);
        String encryptedAESKey = encryptKey(sshKey, aesKey);
        toCompress.setEncryptedAESKey(encryptedAESKey);
        //compress it
        byte[] compressed = compressString(toCompress.getDataForCompression());
        //return the compressed and encrypted data.
        results = compressed;
    } catch(SSHException e) {

        Log.e("SSHFunctions.encryption", "Unable to run the encryption/compression process on the data");
    } catch (UnsupportedEncodingException e) {

        Log.e("SSHFunctions.encryption", "Charset not supported");
    } 

    return results;
}

public static UnencryptedData decompressAndDecrypt(byte[] data, SSHKey sshKey) {

    UnencryptedData results = null;

    try {
        //take the data and decompress it, should result in encryptedData|encryptedAESKey
        byte[] decompressed = decompressString(data);
        String decompressedStr = new String(decompressed, CHAR_SET);
        String[] decompressedArr = decompressedStr.split(SPLIT_STRING);
        //using the users private key decrypt the data
        byte[] decryptedKey = decryptKey(sshKey, decompressedArr[1]);
        EncryptedData encryptedData = new EncryptedData();
        encryptedData.setAesEncryptedData(decompressedArr[0].getBytes(CHAR_SET));
        encryptedData.setIV(decompressedArr[2].getBytes(CHAR_SET)); //TODO: this doesn't seem to decompress correctly
        //create a digest from the decrypted data and compare it with the digest that was included.
        UnencryptedData decryptedDate = decryptDataAES(encryptedData, decryptedKey);
        if(validDigest(decryptedDate)) {

            results = decryptedDate;
        }
        //if equal return the data, if not equal return null
    } catch(Exception e) {

        Log.e("SSHFunctions.decryption", "Unable to run the uncompress/decrypt process on the data");
    }

    return results;
}

public static byte[] decompressString(byte[] toDecompress) {

    ByteArrayInputStream bis = new ByteArrayInputStream(toDecompress);
    byte[] uncompressed;

    try {

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        GZIPInputStream is = new GZIPInputStream(bis);

        byte[] tmp = new byte[256];

        while (true) {

            int r = is.read(tmp);
            if (r < 0) {

                break;
            }
            buffer.write(tmp, 0, r);
        }
        is.close();

        uncompressed = buffer.toByteArray();

        try {
            bis.close();
        } catch (IOException e) {
            ;
        }

        try {
            buffer.close();
        } catch (IOException e) {
            ;
        }
    } catch(IOException e) {

        uncompressed = null;
        Log.e("Zipfunctions.decompress", "Unable to decompress");
    }

    return uncompressed;    
}

public static byte[] compressString(byte[] toCompress) {

    byte[] toCompressBytes = toCompress;
    byte[] compressed;

    ByteArrayOutputStream bos = new ByteArrayOutputStream(toCompressBytes.length);
    try {
        GZIPOutputStream compressor = new GZIPOutputStream(bos);

        compressor.write(toCompressBytes, 0, toCompress.length);
        compressor.close();

        compressed = bos.toByteArray();

        try {
            bos.close();
        } catch(IOException e) {
            ;
        }
    } catch(IOException e) {

        compressed = null;
        Log.e("ZipFunctions.compress", "Unable to compress data");
    }

    return compressed;      
}

最佳答案

您正在尝试实现类似于 OpenPGP 的加密系统。也就是说,您希望使用对称 key 加密任意数量的数据,并与收件人安全地共享该 key (和加密的数据)。

因此,我建议您考虑使用 Java OpenPGP 库 provided by the BouncyCastle team .

他们的许可证是 very permissive 。然而,他们的文档非常糟糕,因此您需要通过 Google 搜索许多示例才能了解如何实现您的目标。

关于Java AES 加密无法正确解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14207813/

相关文章:

Java aes key 到 32 字节字符串表示

java - 如何正确使用 "PBEWithHmacSHA512AndAES_256"算法?

java - 我可以使有关 EulerProblem 的代码更快吗?

java - 如何在 Java 中以编程方式创建 XML 文档?

java - 处理方法不执行所需程序

linux - zcat 文件不适用于 gzip 文件

c - 使用 libgcrypt 使用 aes256-cbc 在 C 中加密和解密文件的问题

java - static volatile boolean - 线程没有被终止

javascript - Node.js中如何解压二进制数据

python - 如何读取gzip : 'GzipFile' object has no attribute 'extrastart' '