KeySets are supported via the GordianKeySetFactory interface.
GordianKnot supports the notion of a KeySet, which is a set of keys of each available algorithm with a 128-bit blockSize. The keySet may be used to encrypt/decrypt and to secure/derive keys or keySets
A keySet can be generated by specifying a GordianKeySetSpec. Each key in the keySet is generated randomly.
/* Access factory */ final GordianFactory myBaseFactory = GordianGenerator.createFactory(); final GordianKeySetFactory myKeySetFactory = myBaseFactory.getKeySetFactory(); /* Create keySet */ final GordianKeySetSpec mySpec = new GordianKeySetSpec(GordianLength.LEN_256); final GordianKeySet myKeySet = myKeySetFactory.generateKeySet(mySpec);
Encryption works by selecting a subSet of the available keys and encrypting the message using each key in turn. The number of keys selected and hence the number of encryption steps is specified in the GordianKeySetSpec and can vary betweeen 3 and 6
/* Access factory */ final GordianFactory myBaseFactory = GordianGenerator.createFactory(); final GordianKeySetFactory myKeySetFactory = myBaseFactory.getKeySetFactory(); /* Create keySet */ final GordianKeySetSpec mySpec = new GordianKeySetSpec(GordianLength.LEN_256); final GordianKeySet myKeySet = myKeySetFactory.generateKeySet(mySpec); /* Encrypt data as one-off */ final byte[] myMessage = ... byte[] myEncrypted = myKeySet.encryptBytes(myMessage); byte[] myResult = myKeySet.decryptBytes(myEncrypted); /* Encrypt data as cipher */ final GordianKeySetCipher myCipher = myKeySet.createCipher(); myCipher.initForEncrypt(); myEncrypted = myCipher.finish(myMessage, 0, myMessage.length); myCipher.initForDecrypt(); myResult = myCipher.finish(myEncrypted, 0, myEncrypted.length);
AAD is supported by calculating a Mac and appending it to the encrypted cipherText. On decryption the Mac is recalculated and compared to the trailing bytes of the cipherText. Encryption works as per normal and the only difference is in the calculation of the Mac. The Mac used is a raw Poly1305 instance, and the algorithm is as follows.
/* Access factory */ final GordianFactory myBaseFactory = GordianGenerator.createFactory(); final GordianKeySetFactory myKeySetFactory = myBaseFactory.getKeySetFactory(); /* Create keySet */ final GordianKeySetSpec mySpec = new GordianKeySetSpec(GordianLength.LEN_256); final GordianKeySet myKeySet = myKeySetFactory.generateKeySet(mySpec); /* Encrypt data as one-off */ final byte[] myAADe = ... final byte[] myMessage = ... byte[] myEncrypted = myKeySet.encryptAADBytes(myMessage, myAAD); byte[] myResult = myKeySet.decryptAADBytes(myEncrypted, myAAD); /* Encrypt data as cipher */ final GordianKeySetAADCipher myCipher = myKeySet.createAADCipher(); myCipher.initForEncrypt(myAAD); myEncrypted = myCipher.finish(myMessage, 0, myMessage.length); myCipher.initForDecrypt(myAAD); myResult = myCipher.finish(myEncrypted, 0, myEncrypted.length);
Wrapping works by selecting a subSet of the available keys and initially encrypting the message with the first key and then using the remaining keys to wrap the result using the standard wrapping algorithm. In each case where the normal cipher is used to encrypt/decrypt, the remaining set of keys is used to encrypt/decrypt in turn.
/* Access factory */ final GordianFactory myBaseFactory = GordianGenerator.createFactory(); final GordianKeySetFactory myKeySetFactory = myBaseFactory.getKeySetFactory(); /* Create keySet */ final GordianKeySetSpec mySpec = new GordianKeySetSpec(GordianLength.LEN_256); final GordianKeySet myKeySet = myKeySetFactory.generateKeySet(mySpec); /* Secure key */ final GordianKey<GordianSymKeySpec> myKey = ... final byte[] mySecured = myKeySet.secureKey(myKey); final GordianKey<GordianSymKeySpec> myResult = myKeySet.deriveKey(mySecured, myKeySpec);
A keySet can also be derived from a password and a hash.
/* Access factory */ final GordianFactory myBaseFactory = GordianGenerator.createFactory(); final GordianKeySetFactory myKeySetFactory = myBaseFactory.getKeySetFactory(); /* Create the hash and access the resultant keySet */ final GordianKeySetSpec mySpec = new GordianKeySetHashSpec(new GordianKeySetSpec(GordianLength.LEN_256)); final char[] myPassword = ... final GordianKeySetHash myKeySetHash = myKeySetFactory.generateKeySetHash(mySpec, myPassword); final GordianKeySet myKeySet = myKeySetHash.getKeySet(); /* Access hash and derive keySet from hash and password */ final byte[] myHash = myKeySetHash.getHash(); final GordianKeySetHash myResolved = myKeySetFactory.deriveKeySetHash(myHash, myPassword);