Java AES加密未正确解密

Java AES加密未正确解密,java,gzip,aes,Java,Gzip,Aes,我在下面的测试中尝试验证AES加密/解密和压缩/解压缩是否正常工作。我有一个加密/解密测试和一个压缩/解压测试,我知道它们各自工作正常,但由于某种原因,当我将它们结合在一起时,解压后IV会出错。我被困住了,不知道还能找什么,有人能给我一些建议或帮助吗?如果我需要发布更多代码,请告诉我。我想我包括了重要的东西 对于上下文:我试图做的是获取一些敏感数据,用AES加密,用RSA公钥加密AES密钥,然后压缩这两段数据,以便它们可以通过网络发送。然后在另一端,我想解压数据,使用RSA私钥来解密AES密钥,

我在下面的测试中尝试验证AES加密/解密和压缩/解压缩是否正常工作。我有一个加密/解密测试和一个压缩/解压测试,我知道它们各自工作正常,但由于某种原因,当我将它们结合在一起时,解压后IV会出错。我被困住了,不知道还能找什么,有人能给我一些建议或帮助吗?如果我需要发布更多代码,请告诉我。我想我包括了重要的东西

对于上下文:我试图做的是获取一些敏感数据,用AES加密,用RSA公钥加密AES密钥,然后压缩这两段数据,以便它们可以通过网络发送。然后在另一端,我想解压数据,使用RSA私钥来解密AES密钥,然后使用它来解密数据。如果有其他方法来实现这一点,我不会把所有的东西都写在自己身上。如果你推荐一个库,请只推荐我可以在商业产品中使用的库

@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;      
}
@测试
public void testEncryptionDecryptionProcesses()引发SShexException{
SSHKey key1=生成密钥对();
UnencryptedData=新的UnencryptedData();
data.setUserName(“hardy”);
data.setHashedPassword(“somepassword”);
数据设置请求(“eat”);
data.setResponse(“”);
setTimestamp(新时间戳(new Date().getTime()).toString());
data.setPublicKeyMod(key1.getPublicMod().toString());
data.setPublicKey(key1.getPublicKey().toString());
byte[]bytes=encryptAndCompress(数据,键1);
assertTrue(字节!=null);
assertTrue(bytes.length>0);
UnencryptedData decryptedData=解压缩和解密(字节,密钥1);
assertEquals(data.getDataForEncryption(),decryptedData.getDataForEncryption());
}
公共静态字节[]encryptAndCompress(未加密数据,SSHKey SSHKey){
字节[]结果=空;
试一试{
字节[]aesKey=createKeyForAES(AES_位长度);
//这应该使用服务器公钥,以便只有服务器可以解密它
//收集数据、获取摘要、加密数据
未加密数据摘要数据=createDigest(数据);
//加密
EncryptedData toCompress=EncryptedDataAES(摘要数据,aesKey);
字符串encryptedAESKey=encryptKey(sshKey,aesKey);
压缩.setEncryptedAESKey(encryptedAESKey);
//压缩它
byte[]compressed=压缩字符串(toCompress.getDataForCompression());
//返回压缩和加密的数据。
结果=压缩;
}捕获(SSE){
Log.e(“SSHFunctions.encryption”,“无法对数据运行加密/压缩过程”);
}捕获(不支持的编码异常e){
Log.e(“SSHFunctions.encryption”,“不支持字符集”);
} 
返回结果;
}
公共静态未加密数据解压缩和解密(字节[]数据,SSHKey SSHKey){
未加密数据结果=空;
试一试{
//获取数据并解压缩,应生成encryptedData | encryptedAESKey
字节[]已解压缩=解压缩字符串(数据);
字符串解压缩DSTR=新字符串(已解压缩,字符集);
String[]decompressedar=decompressedStr.split(split_String);
//使用用户私钥解密数据
byte[]decryptedKey=decryptKey(sshKey,decompressedArr[1]);
EncryptedData EncryptedData=新的EncryptedData();
encryptedData.SetAESEEncryptedData(解压缩数据[0].getBytes(字符集));
encryptedData.setIV(decompressedArr[2].getBytes(CHAR_SET));//TODO:这似乎没有正确解压缩
//从解密的数据创建摘要,并将其与包含的摘要进行比较。
UnencryptedData decryptedDate=DecryptedDataAES(encryptedData,decryptedKey);
if(有效最长(解密日期)){
结果=解密日期;
}
//如果相等,则返回数据;如果不相等,则返回null
}捕获(例外e){
Log.e(“SSHFunctions.decryption”,“无法对数据运行解压缩/解密进程”);
}
返回结果;
}
公共静态字节[]解压字符串(字节[]要解压){
ByteArrayInputStream bis=新的ByteArrayInputStream(待计算);
字节[]未压缩;
试一试{
ByteArrayOutputStream缓冲区=新建ByteArrayOutputStream();
GZIPInputStream is=新的GZIPInputStream(bis);
字节[]tmp=新字节[256];
while(true){
int r=正在读取(tmp);
if(r<0){
打破
}
写缓冲区(tmp,0,r);
}
is.close();
uncompressed=buffer.toByteArray();
试一试{
二、关闭();
}捕获(IOE异常){
;
}
试一试{
buffer.close();
}捕获(IOE异常){
;
}
}捕获(IOE异常){
未压缩=空;
Log.e(“zipffunctions.decompress”,“无法解压缩”);
}
返回未压缩;
}
公共静态字节[]压缩字符串(字节[]压缩){
字节[]toCompressBytes=toCompress;
字节[]压缩;
ByteArrayOutputStream bos=新建ByteArrayOutputStream(toCompressBytes.length);
试一试{
GZIPOutputStream压缩机=新的GZIPOutputStream(bos);
compressor.write(toCompressBytes,0,toCompress.length);
压缩机关闭();
compressed=bos.toByteArray();
试一试{
bos.close();
}捕获(IOE异常){
;
}
}捕获(IOE异常){
压缩=空;
Log.e(“ZipFunctions.compress”,“无法压缩数据”);
}
返回压缩;
}

首先,不应使用字符串分隔符分隔字节缓冲区的各个部分。如果数据中存在分隔符,则会导致问题

我建议你读abo
class TransportData {
private byte[] iv;
private byte[] aesKey;
private byte[] encryptedData;

public TransportData() {
}

public TransportData(byte[] iv, byte[] aesKey, byte[] encryptedData) {
this.iv = iv;
this.aesKey = aesKey;
this.encryptedData = encryptedData;
}

public byte[] encode() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(iv.length);
dos.write(iv);
dos.writeInt(aesKey.length);
dos.write(aesKey);
dos.writeInt(encryptedData.length);
dos.write(encryptedData);
dos.close();
return baos.toByteArray();
}

public void decode(byte[] buffer) throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
DataInputStream dis = new DataInputStream(bais);
iv = new byte[dis.readInt()];
dis.read(iv);
aesKey = new byte[dis.readInt()];
dis.read(aesKey);
encryptedData = new byte[dis.readInt()];
dis.read(encryptedData);
dis.close();
}

public byte[] getAesKey() {
return aesKey;
}
public byte[] getEncryptedData() {
return encryptedData;
}
public byte[] getIv() {
return iv;
}
}