[Nfd-dev] [EXT]Re: Update on NDNCERT protocol

Junxiao Shi shijunxiao at email.arizona.edu
Mon Apr 13 05:17:41 PDT 2020


Hi Zhiyi

I'm trying to implement the protocol in NDNts. I've pasted my
implementation of the crypto operations at the end of this message.
I have unit-tested these operations and they seem to be working. Since
Node.js implements crypto via OpenSSL, this implies OpenSSL has sufficient
primitives for crypto needed by NDNCERT.

I noticed some more issues in the protocol.


Several steps specify the use of signed Interest.
They should also specify which uniqueness assurance fields are required in
the SignatureInfo: SignatureNonce, SignatureTime, SignatureSeqNum.


Several steps specify MustBeFresh in Interest, but lacks FreshnessPeriod in
Data. A Data without FreshnessPeriod cannot satisfy an Interest with
MustBeFresh.
Given signed Interests are unique, it's unnecessary to include MustBeFresh.


Several TLVs are specified as *OCTET in ABNF, but text says "human readable
string".
It also needs to specify what codec to use, such as UTF-8. If you want to
restrict to ASCII instead, specify as *CHAR.
CA profile packet should have FinalBlockId (set to the same as last name
component), so that it is compatible with segmentation convention.


NEW response uses "challenge" TLV-TYPE, but it lacks number assignment.


The AES-GCM session key is established by ECDH followed by HKDF.
WebCrypto cannot directly derive the HKDF key from ECDH. Instead, the
workflow is:

   1. derive bits from ECDH
   2. import bits as HKDF key
   3. derive AES-GCM key from HKDF key

The protocol specifies that the AES-GCM key is 128 bits. However, it does
not specify how many bits go into the HKDF key.
Given ECDH on P-256 curve can establish a shared secret of 256 bits, I'd
recommend specifying 256 bits.


In PROBE/CHALLENGE request, parameter-value is specified as a string.
Some probe methods and challenges may natively use binary information.
Thus, this field could be defined as binary instead.
parameter-key could stay as string, and defined as *CHAR if restricted to
ASCII.


Yours, Junxiao



const ECDH_PARAMS: EcKeyGenParams & EcKeyImportParams = {
  name: "ECDH",
  namedCurve: "P-256",
};

export async function generateEcdhKey(): Promise<CryptoKeyPair> {
  return crypto.subtle.generateKey(ECDH_PARAMS, false, ["deriveBits"]);
}

export async function importEcdhPub(raw: Uint8Array): Promise<CryptoKey> {
  return crypto.subtle.importKey("raw", raw, ECDH_PARAMS, true, []);
}

export async function exportEcdhPub(key: CryptoKey): Promise<Uint8Array> {
  const raw = await crypto.subtle.exportKey("raw", key);
  return new Uint8Array(raw);
}

export async function makeSessionKey(
    ecdhPvt: CryptoKey,
    ecdhPub: CryptoKey,
    salt: Uint8Array,
    requestId: Uint8Array,
): Promise<CryptoKey> {
  const hkdfBits = await crypto.subtle.deriveBits({ name: "ECDH", public:
ecdhPub }, ecdhPvt, 256);
  const hkdfKey = await crypto.subtle.importKey("raw", hkdfBits, "HKDF",
false, ["deriveKey"]);
  return crypto.subtle.deriveKey(
    {
      name: "HKDF",
      salt,
      info: requestId,
      hash: "SHA-256",
    } as any,
    hkdfKey,
    {
      name: "AES-GCM",
      length: 128,
    },
    false,
    ["encrypt", "decrypt"],
  );
}

export interface Encrypted {
  iv: Uint8Array;
  ciphertext: Uint8Array;
}

export async function sessionEncrypt(key: CryptoKey, plaintext: Uint8Array
): Promise<Encrypted> {
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const ciphertext = await crypto.subtle.encrypt({ name: "AES-GCM", iv },
key, plaintext);
  return { iv, ciphertext: new Uint8Array(ciphertext) };
}

export async function sessionDecrypt(key: CryptoKey, { iv, ciphertext }:
Encrypted): Promise<Uint8Array> {
  const plaintext = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key
, ciphertext);
  return new Uint8Array(plaintext);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.lists.cs.ucla.edu/pipermail/nfd-dev/attachments/20200413/cfbe630d/attachment-0001.html>


More information about the Nfd-dev mailing list