Mohit Leekha
Mohit Leekha

Reputation: 61

Compression and Encryption in java and Wp7 mismatch

We have implemented Deflate Compression and AES-128 Encryption in both java and WP7.

When Compression and encryption was implemented as seprate modules they were providing same output on both the platforms.

Later we tried to integrate both modules(ie. input String is compressed first, then compressed string is encrypted), After this integration we are not getting same output on both platforms.

Code is given below

String we are using as input is : "Testing compression(Deflate Algorothjm), encrption(AES algorithm) for WP7."

output for Java : "iJSblymVMAD94KdHSrLt1xLC3lioNc4mNtk4kobuk+qkBEiV4x9Em7ShPxdtXO1EKLjepZVcEvtzCTsmwc5/uGzr4yscgLOvsYvBL8Ku0FM="

output from WP7 : "muMPnBPUG6Ad+zolHtE7Mi9YWTgmm9dOtTWTtZP19oRucf0I02MiHdwIs488y33EGaaZJjQhd3ymaEDOR+HvVb9quQvRu7nkJwXW3uyZEcI="

Java Integrated Code

package com.emap.services;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.zip.Deflater;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class CompressEncrypt {
    static byte[] ibv = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
        0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

    public String compressEncryptData() {

        String strData = "Testing compression(Deflate Algorothjm), encrption(AES algorithm) for WP7.";
        byte[] inputData = strData.getBytes();
        // supporting maximum 10 MB of data
        byte[] outputData = new byte[1024 * 1024 * 10];
        // initiate compressor instance
        Deflater compresser = new Deflater();
        // compressed base64 encoded string

        byte [] compressedByte = null;

        int compressedDataLength = 0;
        //Encrypted String
        String encryptedStr = "";

        try {
            compresser.setInput(inputData, 0, inputData.length);
            compresser.finish();
            compressedDataLength = compresser.deflate(outputData);
            compressedByte = Arrays.copyOfRange(outputData, 0, compressedDataLength);
            System.out.println("Compressed String is : " + compressedByte.toString());
        } catch (Exception ex) {
            System.out.println("Error : " + ex.getMessage());
        }

        try {
            SecretKeySpec skeySpec = new SecretKeySpec("E2D5@eMap_AndIBB".getBytes(), "AES");

            IvParameterSpec iv = new IvParameterSpec(ibv);
            // Instantiate the cipher
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(compressedByte);
            System.out.println("Encrypted String is : " + encrypted.toString());
            encryptedStr = Base64.encode(encrypted);
        }  catch (Exception ex) {
            System.out.println("No Such Padding Error: " + ex.getMessage());
            encryptedStr = "No Such Padding Error: " + ex.getMessage();
        }
        System.out.println("Compressed Encrypted Encoded String is : " + encryptedStr);
        return encryptedStr;
    }
}

WP7 Integrated Code

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using System.Text;
using System.Security;
using System.Security.Cryptography;


namespace CompressEncrypt
{
    public class Code
    {
        static byte[] ibv = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
        0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
        //public string CompressEncode(string strOrigianl)
        public string CompressEncode(string strOrigianl)
        {
            MemoryStream memoryStream = new MemoryStream();
            byte[] getBytes = System.Text.Encoding.UTF8.GetBytes(strOrigianl);

            memoryStream = Deflate(getBytes);
            byte[] objByte = new byte[memoryStream.Length];
            memoryStream.Read(objByte, 0, (int)(memoryStream.Length));
            string strResult = Convert.ToBase64String(memoryStream.ToArray());

            strResult = Encrypt(memoryStream.ToArray(), "E2D5@eMap_AndIBB");
            return strResult;
        }

        MemoryStream Deflate(byte[] data)
        {
            MemoryStream memoryStream = new MemoryStream();
            {
                Deflater deflater = new Deflater();
                using (DeflaterOutputStream outStream = new DeflaterOutputStream(memoryStream, deflater))
                {
                    outStream.IsStreamOwner = false;
                    outStream.Write(data, 0, data.Length);
                    outStream.Flush();
                    outStream.Finish();

                }
                return memoryStream;
            }
        }

        //********************Encryption*************************************
        public string Encrypt(byte[] data, string password)
        {
            AesManaged aes = null;
            MemoryStream memStream = null;
            CryptoStream crStream = null;
            try
            {

                aes = new AesManaged();
                aes.Key = Encoding.UTF8.GetBytes(password);

                aes.IV = ibv;
                memStream = new MemoryStream();
                crStream = new CryptoStream(memStream, aes.CreateEncryptor(), CryptoStreamMode.Write);
                //byte[] data = Encoding.UTF8.GetBytes(dataToEncrypt);
                crStream.Write(data, 0, data.Length);
                crStream.FlushFinalBlock();
                //Return Base 64 String                       
                return Convert.ToBase64String(memStream.ToArray());
            }
            finally
            {
                //cleanup      
                if (crStream != null)
                    crStream.Close();
                if (memStream != null)
                    memStream.Close();
                if (aes != null)
                    aes.Clear();
            }
        }

    }
}

Thanks and Regards Mohit Leekha


As i already Said Seprate Encryption and Compression are Providing same output on both modules.

What i found till now is:

Using "Testing compression(Deflate Algorothjm), encrption(AES algorithm) for WP7." as input string

Compression we converted the string in bytes using byte[] inputData = strData.getBytes(); than compressed these bytes(inputData) using deflater(compressor) we get compressed bytes, after we converted compressd bytes to strin using base64

but in case of WP7 Deflator provide Stream, not bytes Still when we get the same out put on both platforms.

Encryption Same 3 steps(1. conversion to bytes, 2. Encryption 3. conversion to string using base64) we followed for encryption and get same output from both platforms

Integration Problem starts here In java code we converted input string to bytes, compressed it. The Compresser provided Byte Araay , Which is directly passed to Encryption Module ie. skipped 3rd step of compression(conversion of compressed bytes to base64 string) and first step of encryption(conversion of srting to bytes)

When we did this in WP7 we got a stream from the compressor, we converted it to byte array and passed to encryption module, here the output we are getting is different.

Problem with me is my java code is finalized and cannot be altered.

i have a

thanks

Upvotes: 0

Views: 719

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1503140

I believe this is your problem - or at least a problem:

memoryStream = Deflate(getBytes);
byte[] objByte = new byte[memoryStream.Length];
memoryStream.Read(objByte, 0, (int)(memoryStream.Length));

You're writing to the MemoryStream (in Deflate) and then reading from it without resetting the "cursor" to the start. You're also trying to read after the MemoryStream will have been disposed by the DeflaterOutputStream, I suspect.

Fortunately, you don't have to do this at all. Just use:

byte[] objByte = memoryStream.ToArray();

This will work even though the stream is closed.

I note that you're still using String.getBytes() in the Java code without specifying an encoding, by the way. Please don't do that.

Upvotes: 4

Related Questions