GordianKnot Lock

Overview

GordianKnot provide three kinds of locks that are password protected.

  1. 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.
  2. 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.
  3. 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

  1. A random 32-bit seed S and a random 128-bit initVector V are generated.
  2. A seededRandom based on S and the personalisation value I3 is created, and used to create the following items
    1. A set of three hMacs (all different) M1, M2 and M3.
    2. A single secret hMac MS with an 512-bit output.
    3. A 512-bit length digest X is selected from the same seeded Random.
  3. Each of the hMacs is initialised with the password as the key
  4. Each of the macs is updated with P, IV and the number of iterations L
  5. Set input D1-3 and DS to V
  6. Repeat the following loop L times
    1. Update M1 with D2 and D3
    2. Update M2 with D1 and D3
    3. Update M3 with D1 and D2
    4. Update MS with DS and D1-3
    5. Build new DS as the result of MS and xor the result into CS. Repeat for other macs.
  7. Update digest X with C1-3 and calculate the digest as RX
  8. Calculate external lock as the concatenation of S||V||RX
  9. Create keys for the keySet using CS as the secret

Derivation Algorithm

  1. Extract S, V and RX from the external lock.
  2. Repeat creation algorithm with S, V and the password
  3. 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);