用Java加密/解密文件

时间:2013-10-16 20:02:20

标签: java encryption

O想要使用我的Java程序加密和解密文件。 这些文件是编译的Java .class文件,我不知道我做错了什么。我现在只是测试,但是用相同的密钥加密和解密后。它显示该文件是

Exception in thread "AWT-EventQueue-0" java.lang.ClassFormatError: Truncated class file

并且无法加载该类。 有我的加密/解密器类代码:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class EncTool {

public static void encrypt(String key, String filename) throws Throwable {
    InputStream is = new FileInputStream("SomeFile.class");
    OutputStream os = new FileOutputStream("SomeFile.class");
    encrypt(key, Cipher.ENCRYPT_MODE, is, os);
}

public static void decrypt(String key, String filename) throws Throwable {
    InputStream is = new FileInputStream("SomeFile.class");
    OutputStream os = new FileOutputStream("SomeFile.class");
    decrypt(key, Cipher.DECRYPT_MODE, is, os);
}

public static void encrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {

    DESKeySpec dks = new DESKeySpec(key.getBytes());
    SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
    SecretKey desKey = skf.generateSecret(dks);
    Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE

        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        CipherInputStream cis = new CipherInputStream(is, cipher);
        doCopy(cis, os);

}

public static void decrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {

    DESKeySpec dks = new DESKeySpec(key.getBytes());
    SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
    SecretKey desKey = skf.generateSecret(dks);
    Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE

        cipher.init(Cipher.DECRYPT_MODE, desKey);
        CipherOutputStream cos = new CipherOutputStream(os, cipher);
        doCopy(is, cos);

}

public static void doCopy(InputStream is, OutputStream os) throws IOException {
    byte[] bytes = new byte[64];
    int numBytes;
    while ((numBytes = is.read(bytes)) != -1) {
        os.write(bytes, 0, numBytes);
    }
    os.flush();
    os.close();
    is.close();
}

}

并且用于测试即时执行:

    try {
        EncTool.encrypt("somekey123", "SomeFile");
        EncTool.decrypt("somekey123", "SomeFile");
    } catch (Throwable e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

我做错了什么? 或者也许应该怎么做?

编辑

当我的代码看起来:

    public static void encrypt(String key, String filename) throws Throwable {
        InputStream is = new FileInputStream("Somefile.class");
        OutputStream os = new FileOutputStream("tempfile.class");

        DESKeySpec dks = new DESKeySpec(key.getBytes());
        SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
        SecretKey desKey = skf.generateSecret(dks);
        Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE

            cipher.init(Cipher.ENCRYPT_MODE, desKey);
            CipherInputStream cis = new CipherInputStream(is, cipher);
            doCopy(cis, os);

            File file2 = new File("tempfile.class");    

            File f = new File("somefile.class");
            f.delete();
            file2.renameTo(f);
    }

现在它可以工作,但是这些删除和重命名的东西看起来并不优雅,我怎样才能更有效率呢?

1 个答案:

答案 0 :(得分:1)

您必须将输出写入新文件,而不是在读取时覆盖输入。现在编写代码的方式结果将是未定义的。