Class: Toybox.Cryptography.KeyAgreement

Overview

A local private key in combination with a public key to generate a shared secret.

Example:

Create a shared secret using KeyAgreement

// > openssl ec -in key.pem -text -noout
// read EC key
// Private-Key: (224 bit)
// priv:
//     00:89:01:46:f8:bd:64:ce:75:e0:83:02:d0:fc:e1:
//     1d:ce:fd:eb:66:f8:81:1d:68:64:49:05:d3:ee
// pub:
//     04:1d:ba:39:9a:16:6e:62:0b:56:e3:16:73:f7:38:
//     b0:d1:b7:2d:40:ca:92:3a:f8:94:26:24:22:e6:6f:
//     d7:61:db:e8:9b:47:03:33:da:46:0e:6b:36:c9:34:
//     a6:75:6d:d1:10:9f:c2:d7:c6:07:72:bc
// ASN1 OID: secp224r1
// NIST CURVE: P-224

using Toybox.Cryptography;
using Toybox.System;

const PRIVATE_KEY_SECP224R1 = [
    // first byte is not part of the key, so it is omitted
    // 0x00,

    // byte swapped 28 byte (224 bit) word
    0xee, 0xd3, 0x05, 0x49, 0x64, 0x68, 0x1d, 0x81, 0xf8, 0x66, 0xeb, 0xfd, 0xce, 0x1d,
    0xe1, 0xfc, 0xd0, 0x02, 0x83, 0xe0, 0x75, 0xce, 0x64, 0xbd, 0xf8, 0x46, 0x01, 0x89,
]b;

const PUBLIC_KEY_SECP224R1 = [
    // first byte is not part of the key, so it is omitted
    // 0x04,

    // byte swapped 28 byte (224 bit) words
    0xe6, 0x22, 0x24, 0x26, 0x94, 0xf8, 0x3a, 0x92, 0xca, 0x40, 0x2d, 0xb7, 0xd1, 0xb0,
    0x38, 0xf7, 0x73, 0x16, 0xe3, 0x56, 0x0b, 0x62, 0x6e, 0x16, 0x9a, 0x39, 0xba, 0x1d,

    0xbc, 0x72, 0x07, 0xc6, 0xd7, 0xc2, 0x9f, 0x10, 0xd1, 0x6d, 0x75, 0xa6, 0x34, 0xc9,
    0x36, 0x6b, 0x0e, 0x46, 0xda, 0x33, 0x03, 0x47, 0x9b, 0xe8, 0xdb, 0x61, 0xd7, 0x6f,
]b;

// Alice generates a key pair from a private key
var keyPairAlice = new Cryptography.KeyPair({
    :algorithm => Cryptography.KEY_PAIR_ELLIPTIC_CURVE_SECP224R1,
    :privateKey => PRIVATE_KEY_SECP224R1
});

var publicKeyAlice = PUBLIC_KEY_SECP224R1;

// Sanity check Alice's public key matches what we expect
System.println(keyPairAlice.getPublicKey().equals(publicKeyAlice)); // prints 'true'


// Bob generates a key pair from scratch
var keyPairBob = new Cryptography.KeyPair({
    :algorithm => Cryptography.KEY_PAIR_ELLIPTIC_CURVE_SECP224R1
});

var publicKeyBob = keyPairBob.getPublicKey().getBytes();


//
// Alice and Bob exchange public keys
//


// Alice creates a key agreement from her private key
var keyAgreementAlice = new Cryptography.KeyAgreement({
    :protocol => Cryptography.KEY_AGREEMENT_ECDH,
    :privateKey => keyPairAlice.getPrivateKey()
});

// Alice uses Bob's public key to generate a secret known only to Bob and herself
keyAgreementAlice.addKey(keyPairBob.getPublicKey());
var secretKeyAliceAndBob = keyAgreementAlice.generateSecret();


// Bob creates a key agreement from his private key
var keyAgreementBob = new Cryptography.KeyAgreement({
    :protocol => Cryptography.KEY_AGREEMENT_ECDH,
    :privateKey => keyPairBob.getPrivateKey()
});

// Bob uses Alice's public key to generate a secret known only to and Alice and himself
keyAgreementBob.addKey(keyPairAlice.getPublicKey());
var secretKeyBobAndAlice = keyAgreementBob.generateSecret();


// Bob and Alice now have a shared secret without exposing either of
// their private keys. This secret can be used to sign or encrypt
// messages between Alice and Bob. Sanity check shared secret is same
// for both Alice and Bob.
System.println(secretKeyAliceAndBob.equals(secretKeyBobAndAlice)); // prints 'true'

Since:

API Level 3.0.0

Supported Devices:

Instance Method Summary collapse

Instance Method Details

addKey(key as Cryptography.Key) as Void

Add a public Key to KeyAgreement.

Parameters:

Since:

API Level 3.0.0

Throws:

generateSecret() as Lang.ByteArray

Generate a shared secret for the KeyAgreement.

Returns:

Since:

API Level 3.0.0

initialize(options as { :protocol as Cryptography.KeyAgreementProtocol, :privateKey as Cryptography.Key })

Constructor

Parameters:

Since:

API Level 3.0.0

Throws:


Generated Dec 11, 2024, 8:58:43 AM