简体   繁体   English

Java加密:从文件加载对称密钥

[英]Java Encryption: Loading a symmetric key from file

So recently I've started working with encryption. 所以最近我开始使用加密。 I have a functioning asymmetric encryption class, but I need a symmetric key class as well. 我有一个正常运行的非对称加密类,但是我也需要一个对称密钥类。 Although most aspects of the symmetric key class are working, loading a key from it's encoded bytes is not. 尽管对称密钥类的大多数方面都可以使用,但是不能从编码字节中加载密钥。 The following is the symmetric key class. 以下是对称密钥类。 I've marked the two constructors that are not working. 我已经标记了两个无效的构造函数。

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);
}

}

Running with the following test code produces a java.security.InvalidKeyException : 使用以下测试代码运行会产生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)));

The exception: 例外:

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)

Test 38 is the System.out.println call, and PlasmaSymmetricEncrypter 96 is here 测试38是System.out.println调用,而PlasmaSymmetricEncrypter 96在此处

All my code is on github 我所有的代码都在github上

Edits for clarity: 1. Please ignore the encrypt to string methods, they will be replaced with base64 encoding once I have this issue resolved. 为清楚起见,进行编辑:1.请忽略“加密为字符串”方法,一旦我解决了这个问题,它们将被base64编码替换。 2. The error does not occur in the constructor itself, it is only thrown when I attempt to get a cipher for the reconstructed key. 2.该错误不会在构造函数本身中发生,仅当我尝试获取重构密钥的密码时才会抛出该错误。

So, I was dumb. 所以,我很傻。

Within my test code, I was constructing the SymmetricEncrypter like so: 在测试代​​码中,我正在像这样构造SymmetricEncrypter:

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

Using the RSA algorithm, which, of course does not work for symmetric keys. 使用RSA算法,该算法当然不适用于对称密钥。

Thanks to those that tried to help, but in the end it was my test code that was failing, not the class. 多亏了那些试图提供帮助的人,但最终导致失败的是我的测试代码,而不是该类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM