GordianKnot Lock
Overview
GordianKnot provide three kinds of locks that are password protected.
- keySetLocks are provided to secure a keySet using a password. This keySet can be automatically generated or be pre-existing. It can only be unlocked by the same factory that was used to lock it.
- factoryLocks are provided to secure a factory using a password. The factory to be locked can be automatically generated or be pre-existing. It can be unlocked by any factory running on the same machine.
- keyPairLocks are provided to secure a randomly generated keySet using a password and a private asymmetric key. It can be unlocked using any factory and the corresponding public asymmetric key.
Password Algorithm
Creation Algorithm
- A random 32-bit seed S and a random 128-bit initVector V are generated.
- A seededRandom based on S and the personalisation value
I3 is created, and used to create the following items
- A set of three hMacs (all different) M1, M2 and M3.
- A single secret hMac MS with an 512-bit output.
- A 512-bit length digest X is selected from the same seeded Random.
- Each of the hMacs is initialised with the password as the key
- Each of the macs is updated with P, IV and the number of iterations L
- Set input D1-3 and DS to V
- Repeat the following loop L times
- Update M1 with D2 and D3
- Update M2 with D1 and D3
- Update M3 with D1 and D2
- Update MS with DS and D1-3
- Build new DS as the result of MS and xor the result into CS. Repeat for other macs.
- Update digest X with C1-3 and calculate the digest as RX
- Calculate external lock as the concatenation of S||V||RX
- Create keys for the keySet using CS as the secret
Derivation Algorithm
- Extract S, V and RX from the external lock.
- Repeat creation algorithm with S, V and the password
- Compare the calculated RX with the one extracted from the hash. Only create the keySet if it matches.
keySetLock
A keySetLock can be either be used to secure an existing keySet, or it can be used to create a new random keySet.
Sample
/* Access factory */
final GordianFactory myBaseFactory = GordianGenerator.createFactory();
final GordianLockFactory myLockFactory = myBaseFactory.getLockFactory();
/* Create a lock for a new keySet */
final GordianPasswordLockSpec mySpec = new GordianPasswordLockSpec(new GordianKeySetSpec(GordianLength.LEN_256));
final char[] myPassword = ...
final GordianKeySetLock myLock = myLockFactory.newKeySetLock(mySpec, myPassword);
final GordianKeySet myKeySet = myLock.getKeySet();
final byte[] myLockBytes = myLock.getLockBytes();
/* Resolve the lock */
final GordianKeySetLock myResolved = myLockFactory.resolveKeySetLock(myLockBytes, myPassword);
factoryLock
A factoryLock can either be used to secure an existing factory, or it can be used to create a new random factory.
Sample
/* Access factory */
final GordianFactory myBaseFactory = GordianGenerator.createFactory();
final GordianLockFactory myLockFactory = myBaseFactory.getLockFactory();
final GordianKeySetFactory myKeySetFactory = myKeySetFactory.getKeySetFactory();
/* Create a lock for a new factory */
final GordianPasswordLockSpecBuilder myLockBuilder = myLockFactory.newPasswordLockSpecBuilder()
final GordianKeySetSpecBuilder myKeySetBuilder = myKeySetFactory.newKeySetSpecBuilder()
final GordianPasswordLockSpec mySpec = myLockBuilder.passwordLock(myKeySetBuilder.keySet(GordianLength.LEN_256));
final char[] myPassword = ...
final GordianFactoryLock myLock = myBaseFactory.newFactoryLock(mySpec, myPassword);
final GordianFactory myFactory = myLock.getFactory();
final GordianKeySet myKeySet = myFactory.getEmbeddedKeySet();
final byte[] myLockBytes = myLock.getLockBytes();
/* Resolve the lock */
final GordianFactoryLock myResolved = myBaseFactory.resolveFactoryLock(myLockBytes, myPassword);
keyPairLock
A keyPairLock can be used to create a new secured random keySet using an agreement-capable keypair.
Sample
/* Access factory */
final GordianFactory myBaseFactory = GordianGenerator.createFactory();
final GordianLockFactory myLockFactory = myBaseFactory.getLockFactory();
final GordianKeySetFactory myKeySetFactory = myBaseFactory.getKeySetFactory();
final GordianAsyncFactory myAsyncFactory = myBaseFactory.getAsyncFactory();
final GordianKeyPairFactory myKeyPairFactory = myAsyncFactory.getKeyPairFactory();
final GordianAgreementFactory myAgreementFactory = myAsyncFactory.getAgreementFactory();
/* Access keyPairGenerator and create sending/receiving pairs */
final GordianKeyPairSpecBuilder myKeyPairBuilder = myKeyPairFactory.newKeyPairkSpecBuilder()
final GordianKeyPairSpec mySpec = myKeyPairBuilder.dh(GordianDHGroup.FFDHE2048);
final GordianKeyPairGenerator myGenerator = myKeyPairFactory.getKeyPairGenerator(mySpec);
final GordianKeyPair myKeyPair = myGenerator.generateKeyPair();
/* Create a lock for a new keySet */
final GordianKeySetSpecBuilder myKeySetBuilder = myKeySetFactory.newKeySetSpecBuilder()
final GordianPasswordLockSpecBuilder myLockBuilder = myLockFactory.newPasswordLockSpecBuilder()
final GordianPasswordLockSpec mySpec = myLockBuilder.keySet(myKeySetBuilder(GordianLength.LEN_256));
final char[] myPassword = ...
final GordianKeyPairLock myLock = myLockFactory.newKeyPairLock(mySpec, myKeyPair, myPassword);
final GordianKeySet myKeySet = myLock.getKeySet();
final byte[] myLockBytes = myLock.getLockBytes();
/* Resolve the lock */
final GordianKeyPairLock myResolved = myLockFactory.resolveKeyPairLock(myLockBytes, myKeyPair, myPassword);
