Thanks to visit codestin.com
Credit goes to github.com

Skip to content

aparcar/qudas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Qudas

Tool to simplify QKD migration by providing a (PQC) secret based ETSI-014 API.

Usage

Start the server:

echo "super_secret" > secret.txt
cargo r -- --secret-path secret.txt --addr 127.0.0.1:12345 &
cargo r -- --secret-path secret.txt --addr 127.0.0.1:12346 &

Request a fresh key via curl:

curl -s -v http://localhost:12345/api/v1/keys/sae_ada/enc_keys?number=1 | jq
{
  "keys": [
    {
      "key": "ZvmDBb77+1pMHvGHe0CXLAZyhgU6kE8PPwlR/bCo3dw=",
      "key_ID": "36f0b2eb-066e-4151-97ae-26ff766806f1"
    }
  ]
}

The key_ID is now added to the internal registry and can't be requested again, however a second instance with the same shared secred returns the key as follows:

curl -s -v http://localhost:12346/api/v1/keys/sae_ada/dec_keys?key_ID=36f0b2eb-066e-4151-97ae-26ff766806f1 | jq
{
  "keys": [
    {
      "key": "ZvmDBb77+1pMHvGHe0CXLAZyhgU6kE8PPwlR/bCo3dw=",
      "key_ID": "36f0b2eb-066e-4151-97ae-26ff766806f1"
    }
  ]
}

Implementation Details

Some details about the implementation.

ETSI-014

Two API calls:

/enc_keys

returns a new key_ID (UUIDv4) and key (base64([u8; 32]))

/dec_keys?key_ID=<key_ID>

returns <key_ID> (UUIDv4) and key (base64([u8; 32]))

This is normally QKD based and fetched from a database, but could be generated based on a shared secret.

Trivial Implementation

Combine the shared secret with a random UUID and use that as secret key.

/enc_keys

secret = "very_secret"
key_id = uuid_v4()
new_key = hash(secret | key_id)

return { "key_ID": key_id, "key": new_key }

/dec_keys?key_ID=<key_ID>

secret = "very_secret"
key_id = url.get_param("key_ID")
new_key = hash(secret | key_id)

return { "key_ID": key_id, "key": new_key }

Problem

What if the shared secret changes and is not 100% in sync between both instances? Different keys are generated without the consuming end device knowing about it.

Secondly a hash isn't recommended for this purpose, use a HKDF which offers different key lengths.

Solution

Add a hash of the secret to the key_ID and verify the ID's match, if not ask the client to retry by sending a 404 Not Found.

Improved Approach

/enc_keys

secret = "very_secret"
secret_hash = hash(secret)

key_id = secret_hash[0..2] | uuid_v4()[2..16]

new_key = hkdf(secret | key_id)

return { "key_ID": key_id, "key": new_key }

/dec_keys?key_ID=<key_ID>

secret = "very_secret"
secret_hash = hash(secret)

key_id = url.get_param("key_ID")

if key_id[0..2] != secret_hash[0..2]
    return "key_not_found"

new_key = hkdf(secret | key_id)

return { "key_ID": key_id, "key": new_key }

ToDo

  • Add /api/v1/status command
  • Implement limit how many keys can be used per secret
  • Implement size parameter

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages