文件加密,密钥大小问题

时间:2014-04-12 07:08:07

标签: java encryption des

这是一个示例代码,通过它我试图读取文件并加密/解密(如果密钥已知正确解密)问题是代码被锁定以接受长度为8的密钥,任何高于或低于的密钥都是发出运行时错误说明:

Exception in thread "main" java.security.InvalidKeyException: Invalid key length: 11     bytes
at com.sun.crypto.provider.DESCipher.engineGetKeySize(DESCipher.java:373)
at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1052)
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1010)
at javax.crypto.Cipher.implInit(Cipher.java:786)
at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
at javax.crypto.Cipher.init(Cipher.java:1213)
at javax.crypto.Cipher.init(Cipher.java:1153)
at custom_enc.Custom_enc.encrypt(Custom_enc.java:50)
at custom_enc.Custom_enc.main(Custom_enc.java:105)
Java Result: 1

类别:

package custom_enc;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Scanner;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.SecretKeySpec;
public class Custom_enc {

String ekey="";
String algorithm="";
String path1="";
File f;

public void Custom_enc()
{
    System.out.println("Enter the file name with extension and path : \n");
    Scanner s = new Scanner(System.in);
    String path1 = s.nextLine();
    f = new File(path1);
    System.out.println("Enter secret key : \n");
    ekey = s.nextLine();
}

public void encrypt() throws Exception
{
   Custom_enc();
   this.algorithm="DES/ECB/PKCS5Padding";
    FileInputStream fis =new FileInputStream(f);
    f=new File(f.getAbsolutePath()+"_encrypted_file.txt");
    FileOutputStream fos =new FileOutputStream(f);

    byte k[] = ekey.getBytes();
    SecretKeySpec key = new SecretKeySpec(k,"DES");
    Cipher encrypt = Cipher.getInstance(algorithm);

    encrypt.init(Cipher.ENCRYPT_MODE, key);
    CipherOutputStream cout=new CipherOutputStream(fos, encrypt);
    byte[] buf = new byte[1024];
    int read;

    while((read=fis.read(buf))!=-1) //reading data
        cout.write(buf,0,read); //writing encrypted data

    fis.close();
    cout.flush();
    cout.close();
    System.out.println("Encryption Done!!");
    //exit();
}

public void decrypt() throws Exception
{
    Custom_enc();
    this.algorithm="DES/ECB/PKCS5Padding";
    FileInputStream fis =new FileInputStream(f);
    f=new File(f.getAbsolutePath()+"_decrypted_file.txt");
    FileOutputStream fos =new FileOutputStream(f);

    byte k[] = ekey.getBytes();
    SecretKeySpec key = new SecretKeySpec(k,"DES");

    Cipher decrypt = Cipher.getInstance(algorithm);
    decrypt.init(Cipher.DECRYPT_MODE, key);
    CipherInputStream cin=new CipherInputStream(fis, decrypt);

    byte[] buf = new byte[1024];
    int read=0;

    while((read=cin.read(buf))!=-1) //reading encrypted data
    {
        fos.write(buf,0,read); //writing decrypted data
    }

    cin.close();
    fos.flush();
    fos.close();

    System.out.println("Encryption Done!!");
    //1exit();

}

public static void main(String[] args) throws Exception,     java.security.InvalidKeyException {
    Custom_enc obj = new Custom_enc();
    System.out.println("Enter your choice : \n 1 For Encryption \n 2 For Decryption");
    Scanner s1 = new Scanner(System.in);
    int choice = s1.nextInt();
    if(choice==1)
    {
        System.out.println("You've chosen to Encrypt\n");
        obj.encrypt();
    }
    else if(choice==2)
    {
        System.out.println("You've chosen to Decrypt\n");
        obj.decrypt();
    }
    else
    {
        System.out.println("Invalid Choice, Try again...");
    }
}

}

2 个答案:

答案 0 :(得分:0)

是的,DES使用64位密钥(尽管有效密钥大小仅为56位)。 64位是8个字节,因此这是你的密钥长度。

例如,您可以使用散列将较长的密码缩小为64位,并使用该密码。

答案 1 :(得分:0)

问题是您要混淆密码或密码短语和密钥; 密码不是密钥

然而,可以从密钥派生密码。您应该使用基于密码的密钥派生函数(PBKDF)来执行此操作。其中有一些可以安全使用:scrypt,bcrypt和PBKDF2。后者也存在于Java的标准Oracle实现中。它是Java中支持基于密码的加密(PBE)的功能的一部分,如PKCS#5标准中所述。

参见例如关于如何利用PBKDF2的代码in this question。请注意,您必须创建一个salt(64位或更多的安全随机值)并添加与密文一起存储它。