0

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.

Socratic Phoenix
  • 556
  • 1
  • 7
  • 19
  • String is not a container for binary data. Get rid of the methods that return ciphertext as a String or that return plaintext from a String parameter. – user207421 Dec 22 '15 at 03:47
  • Yes, I know, they were for testing purposes only. – Socratic Phoenix Dec 22 '15 at 04:00
  • Cannot reproduce. The constructor you name works for me with both algorithms. Try deleting your symmetric key file, it may be junk left over from some prior non-working state. – user207421 Dec 22 '15 at 04:00
  • No luck... I'm running windows 10 - I suppose its possible you have a library i don't... I guess intellij could be doing something, but I don't see why. The error says there is no installed provider... perhaps you have one and i don't. – Socratic Phoenix Dec 22 '15 at 04:11
  • Oh, I should note, the constructor doesn't fail until I attempt to encrypt/decrypt something, the Cipher can't find anything for the key, yet the key itself seems to load fine – Socratic Phoenix Dec 22 '15 at 04:22
  • The constructor doesn't encrypt or decrypt anything, ergo it can't fail while doing so. Unclear what you're talking about. – user207421 Dec 22 '15 at 06:02
  • What I mean is the constructor does not throw an error, but the getting of a cipher (in encrypt/decrypt methods) does, but only after using the marked constructors – Socratic Phoenix Dec 22 '15 at 10:29
  • It's been resolved. Thank you for your help @EJP – Socratic Phoenix Dec 22 '15 at 16:32

1 Answers1

1

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.

Socratic Phoenix
  • 556
  • 1
  • 7
  • 19