0

I have a compiled native program that is encrypted for security (an encrypted exe file for example). I want to run it without writing a plaintext (unecnrypted) copy to the users harddrive. I know native programs can be run using java's runtime class, but I'd like to be able to run the encrypted version. How can I both decrypt and run a native program in Java without writing the unencrypted data to the disk. Can I execute a byte array at runtime in Java? If so, do I have to use JNA/JNI?

Also, is this possible with a non-native proprietary file type such as Microsoft Word Document or PDF?

If possible, I'd like to avoid using third party software such as TrueCrypt.

Thanks in advance for any help.

guyfleeman
  • 463
  • 7
  • 22
theAnonymous
  • 1,701
  • 2
  • 28
  • 62
  • I think you're going have to clarify your question, I've read it like 4 times and still don't know what it is you're asking. From the sounds of it, you have encrypted some data into a file and/database and what to know if there is some way to load it via some other process? Yes, if you provide the means by which that content can be decrypted... – MadProgrammer Jul 31 '14 at 04:07
  • 1
    hummm a hacker job... I think here this is not the place to such a thing. – Jorge Campos Jul 31 '14 at 04:09
  • Hello, please assume that the byte array in memory is decrypted, I am primarily concerned about the HDD activity. What are the method/JPA/JNI methods that I should be looking into? – theAnonymous Jul 31 '14 at 04:09
  • I suppose in theory if you emulated a PC in Java, you could emulate an in-memory operating system in there that could run whatever application you want. I think the practical answer to your questions though, is 'no'. Edit: I guess you could load an EXE into your process's address space manually, by doing all the loading/linking/mapping stuff yourself, and then jumping to the address of the entry point. I think that would work, but it's a lot of work. – Boann Jul 31 '14 at 04:12
  • 1
    Use a traditional ramdisk? – hyde Jul 31 '14 at 04:26
  • 1
    You would have more hope if the binaries *were* Java. Then you could just write a custom classloader. If you want to execute encrypted EXEs you will have to reimplement all the operating system's loading etc, which I doubt is even feasible in general. – user207421 Jul 31 '14 at 04:50

1 Answers1

2

I believe CipherInputStream might help you. It functions just like a normal InputStream object but also applies a Cipher (either encryption or decryption). If you want to read a file in non-plain text, write the file with a CipherOutputStream, then read it normally like any other file with a CipherInputStream on the other end.

If your file is already encrypted, which it sound like it is, you'd only need the CipherInputStream initialized to whatever encryption method was used to create the native code.

        FileInputStream in = new FileInputStream("YOUR DIRECTORY");
        Cipher decryptionCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, createKey(password));

        CipherInputStream ciphIn = new CipherInputtStream(in, decryptionCipher);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[8];
        int i = in.read(buffer);
        while (i != -1)
        {
            //just like a file copy
            out.write(buffer, 0, i)
            i = in.read(buffer);
        }

        /*
         * YOUR NATIVE DATA UNENCRYPTED
         */
        byte[] nativeFileData = out.toByteArray();

        ciphIn.close();
        in.close();

The create key method:

public SecretKey createKey(String password) throws NoSuchAlgorithmException, InvalidKeySpecException
{
        //hash the password
        MessageDigest msgDigest = MessageDigest.getInstance("SHA-1");
        msgDigest.update(key);
        byte[] hash = msgDigest.digest();

        byte[] salt = new byte[8]{};
        new SecureRandom(hash).nextBytes(salt);

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec keySpec = new PBEKeySpec(hash, salt, 65536, 128);
        SecretKey tmp = factory.generateSecret(keySpec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

        return secret;
}

You would now have a byte array containing your native unencrypted bytes. So now you could run this (assuming its like an exe or something) using a JNI/JNA class. It is possible to load native code into memory. That memory is then allocated as executable and you can run it as assembly instructions by using a native system call. There's is already a stack overflow article about doing this located here. It will be up to you to implement it in JNI format.

In terms of opening a PDF/DOCS file, you're talking about reading a proprietary file format, using a proprietary program who's system call interface you know nothing about. I am also confused as to why the user can open these files and view the content but they cant have access to the file. If you could clarify that would be great. What you could do is take this byte array and use a library to render the pdf to png images, then use javafx to display the images.

I know this answer isn't spot on but I hope it helps or at least points you in the right direction.

Cheers.

Community
  • 1
  • 1
guyfleeman
  • 463
  • 7
  • 22
  • 1
    You can now run the byte array ***how?*** – user207421 Jul 31 '14 at 05:17
  • You can load a byte array in C/C++ into executable memory using a native system call VirtualProtect() and then execute that memory as assembly instructions. There is a C++ stackoverflow question on this topic already. I did not see this as in the context of what the user was asking, but after you pointed it out I see that I missed it. Thanks. I'll edit the question. – guyfleeman Jul 31 '14 at 05:27