简体   繁体   中英

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 :

    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

All my code is on 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. 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.

So, I was dumb.

Within my test code, I was constructing the SymmetricEncrypter like so:

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

Using the RSA algorithm, which, of course does not work for symmetric keys.

Thanks to those that tried to help, but in the end it was my test code that was failing, not the class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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