Java—我可以运行加密的本机可执行文件而不先将其写入硬盘吗?

Java—我可以运行加密的本机可执行文件而不先将其写入硬盘吗?,java,encryption,java-native-interface,runtime,native,Java,Encryption,Java Native Interface,Runtime,Native,我有一个经过编译的本机程序,它是为了安全而加密的(例如加密的exe文件)。我想在不向用户硬盘写入纯文本(未加密)副本的情况下运行它。我知道本机程序可以使用java的runtime类运行,但我希望能够运行加密版本。如何在不将未加密的数据写入磁盘的情况下用Java解密并运行本机程序。我可以在Java运行时执行字节数组吗?如果是这样,我必须使用JNA/JNI吗 另外,对于非本机专有文件类型(如Microsoft Word文档或PDF),是否可以这样做 如果可能,我希望避免使用第三方软件,如TrueCr

我有一个经过编译的本机程序,它是为了安全而加密的(例如加密的exe文件)。我想在不向用户硬盘写入纯文本(未加密)副本的情况下运行它。我知道本机程序可以使用java的runtime类运行,但我希望能够运行加密版本。如何在不将未加密的数据写入磁盘的情况下用Java解密并运行本机程序。我可以在Java运行时执行字节数组吗?如果是这样,我必须使用JNA/JNI吗

另外,对于非本机专有文件类型(如Microsoft Word文档或PDF),是否可以这样做

如果可能,我希望避免使用第三方软件,如TrueCrypt


提前感谢您的帮助。

我相信CipherInputStream可能会帮助您。它的功能与普通InputStream对象类似,但也应用密码(加密或解密)。如果要读取非纯文本文件,请使用CipherOutputStream写入该文件,然后像读取另一端具有CipherInputStream的其他文件一样正常读取该文件

如果您的文件已经加密(听起来像是这样),那么您只需要将CipherInputStream初始化为创建本机代码所使用的任何加密方法

        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();
创建密钥方法:

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;
}
现在,您将拥有一个包含本机未加密字节的字节数组。所以现在您可以使用JNI/JNA类运行它(假设它类似于exe或其他东西)。可以将本机代码加载到内存中。然后将该内存分配为可执行文件,您可以使用本机系统调用将其作为汇编指令运行。已经有一篇关于执行此操作的堆栈溢出文章。将由您以JNI格式实现它

在打开PDF/DOCS文件方面,您所说的是读取一种专有文件格式,使用一个您一无所知的专有程序的系统调用接口。我还不明白为什么用户可以打开这些文件并查看内容,但他们无法访问该文件。如果你能澄清一下,那就太好了。您可以使用这个字节数组并使用库将pdf渲染为png图像,然后使用javafx显示图像

我知道这个答案并不准确,但我希望它能帮助你,或者至少能为你指明正确的方向


干杯

我想你必须澄清你的问题,我已经读了4遍了,但仍然不知道你在问什么。从听起来,您已经将一些数据加密到了文件和/或数据库中,如果有其他方法可以通过其他进程加载,您该知道些什么?是的,如果你提供解密这些内容的方法…我是个黑客。。。我认为这里不是做这种事情的地方。您好,请假设内存中的字节数组被解密,我主要关心的是硬盘的活动。我应该研究的/JPA/JNI方法是什么?使用传统的ramdisk?如果二进制文件是Java,您会有更多的希望。然后您就可以编写一个自定义类加载器。如果要执行加密的示例,必须重新实现所有操作系统的加载等,我怀疑这在一般情况下是否可行。您现在可以如何运行字节数组?您可以使用本机系统调用VirtualProtect()将C/C++中的字节数组加载到可执行内存中,然后将该内存作为汇编指令执行。这个主题已经有C++ StaskOp溢出问题了。我不认为这是在用户询问的上下文中,但在您指出后,我发现我错过了它。谢谢我将编辑这个问题。