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.
Sample
/* 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);
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();
/* Create a lock for a new factory */
final GordianPasswordLockSpec mySpec = new GordianPasswordLockSpec(new GordianKeySetSpec(GordianLength.LEN_256));
final char[] myPassword = ...
final GordianFactoryLock myLock = myLockFactory.newFactoryLock(mySpec, myPassword);
final GordianFactory myFactory = myLock.getFactory();
final GordianKeySet myKeySet = myFactory.getEmbeddedKeySet();
final byte[] myLockBytes = myLock.getLockBytes();
/* Resolve the lock */
final GordianFactpryLock myResolved = myLockFactory.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 GordianKeyPairFactory myKeyPairFactory = myBase.getKeyPairFactory();
final GordianAgreementFactory myAgreementFactory = myKeyPairFactory.getAgreementFactory();
/* Access keyPairGenerator and create sending/receiving pairs */
final GordianKeyPairSpec mySpec = GordianKeyPairSpec.dh(GordianDHGroup.FFDHE2048);
final GordianKeyPairGenerator myGenerator = myKeyPairFactory.getKeyPairGenerator(mySpec);
final GordianKeyPair myKeyPair = myGenerator.generateKeyPair();
/* Create a lock for a new keySet */
final GordianPasswordLockSpec mySpec = new GordianPasswordLockSpec(new GordianKeySetSpec(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);