2015-12-22 82 views
0

所以最近我开始使用加密。我有一个功能非对称加密类,但我也需要一个对称密钥类。虽然对称密钥类的大多数方面都在起作用,但从其编码字节中加载密钥不是。以下是对称密钥类。我标记了两个不起作用的构造函数。Java加密:从文件加载对称密钥

public class PlasmaSymmetricEncrypter { 
public static String DESEDE_ALGORITHM = "DESede"; 
public static String AES_ALGORITHM = "AES"; 

private Key key; 
private String algorithm; 


public PlasmaSymmetricEncrypter(Key key) { 
    this.key = key; 
    this.algorithm = key.getAlgorithm(); 
} 

public PlasmaSymmetricEncrypter(File keyFile, String algorithm) throws IOException, NoSuchAlgorithmException { //This constructor is not working 
    this.algorithm = algorithm; 
    if(!keyFile.exists()) { 
     this.genKey(keyFile); 
    } 

    Key key = new SecretKeySpec(Files.readAllBytes(keyFile.toPath()), algorithm); 
    this.key = key; 
} 

public PlasmaSymmetricEncrypter(byte[] key, String algorithm) { //This constructor is not working 
    this(new SecretKeySpec(key, algorithm)); 
} 

private void genKey(File file) throws NoSuchAlgorithmException, IOException { 
    KeyGenerator generator = KeyGenerator.getInstance(this.algorithm); 
    this.key = generator.generateKey(); 
    file.delete(); 
    if(file.getParentFile() != null) { 
     file.getParentFile().mkdirs(); 
    } 
    file.createNewFile(); 
    FileOutputStream stream = new FileOutputStream(file); 
    stream.write(this.getEncodedKey()); 
    stream.close(); 
} 

public byte[] getEncodedKey() { 
    return this.key.getEncoded(); 
} 

public byte[] encrypt(byte[] bytes) throws BadPaddingException, IllegalBlockSizeException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException { 
    Cipher cipher = Cipher.getInstance(this.algorithm); 
    cipher.init(Cipher.ENCRYPT_MODE, this.key); 
    return cipher.doFinal(bytes); 
} 

public byte[] encrypt(String text) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { 
    return this.encrypt(text.getBytes(StandardCharsets.UTF_8)); 
} 

public String decrypt(byte[] bytes) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { 
    Cipher cipher = Cipher.getInstance(this.algorithm); 
    cipher.init(Cipher.DECRYPT_MODE, this.key); 
    return new String(cipher.doFinal(bytes), StandardCharsets.UTF_8); 
} 

public String decrypt(String bytes) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { 
    return this.decrypt(bytes.getBytes(StandardCharsets.ISO_8859_1)); 
} 

public String encryptToString(String text) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { 
    return new String(this.encrypt(text), StandardCharsets.ISO_8859_1); 
} 

} 

用下面的测试代码运行产生java.security.InvalidKeyException

PlasmaAsymmetricEncrypter asymmetricEncrypter = new PlasmaAsymmetricEncrypter(new File("private.key"), new File("public.key"), PlasmaAsymmetricEncrypter.RSA_ALGORITHM); 
    PlasmaSymmetricEncrypter symmetricEncrypter = new PlasmaSymmetricEncrypter(new File("secret.key"), PlasmaSymmetricEncrypter.AES_ALGORITHM); 
    String encrypt = "hello world"; 
    byte[] encryptedKey = asymmetricEncrypter.encryptPrivate(symmetricEncrypter.getEncodedKey()); 
    PlasmaSymmetricEncrypter encrypter = new PlasmaSymmetricEncrypter(asymmetricEncrypter.decryptPublic(encryptedKey), PlasmaAsymmetricEncrypter.RSA_ALGORITHM); 
    System.out.println(encrypter.decrypt(symmetricEncrypter.encrypt(encrypt))); 

例外:

Exception in thread "main" java.security.InvalidKeyException: No installed provider supports this key: javax.crypto.spec.SecretKeySpec 
    at javax.crypto.Cipher.chooseProvider(Cipher.java:893) 
    at javax.crypto.Cipher.init(Cipher.java:1249) 
    at javax.crypto.Cipher.init(Cipher.java:1186) 
    at com.gmail.socraticphoenix.plasma.file.encryption.PlasmaSymmetricEncrypter.decrypt(PlasmaSymmetricEncrypter.java:96) 
    at com.gmail.socraticphoenix.plasma.Test.main(Test.java:38) 

测试38是System.out.println呼叫,并且PlasmaSymmetricEncrypter 96是here

我的所有代码都在上

为清晰起见进行编辑: 1.请忽略对字符串方法的加密,一旦解决此问题,它们将被替换为base64编码。 2.错误不在构造函数本身中发生,只有当我尝试获取重建密钥的密码时才会出现该错误。

+0

字符串不是二进制数据的容器。摆脱将密文返回为String或从String参数返回明文的方法。 – EJP

+0

是的,我知道,它们仅用于测试目的。 –

+0

无法重现。你名字的构造函数适用于两种算法。尝试删除您的对称密钥文件,它可能是某些以前的非工作状态遗留下来的垃圾。 – EJP

回答

1

所以,我很笨。

在我的测试代码,我是构建SymmetricEncrypter像这样:

PlasmaSymmetricEncrypter encrypter = new PlasmaSymmetricEncrypter(asymmetricEncrypter.decryptPublic(encryptedKey), PlasmaAsymmetricEncrypter.RSA_ALGORITHM); 

使用RSA算法,这当然不适合对称密钥工作。

感谢那些试图提供帮助的人,但最终我的测试代码失败了,而不是课程。