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

Zhiyi Zhang zhiyi at cs.ucla.edu
Mon Apr 13 21:20:14 PDT 2020


Hi Davide and Junxiao,

Thank you for your comments. I just pushed updates.

* All strings are specified as UTF 8 encoded
* I made a separate section 2.3.3 to clarify the use of HKDF in NDNCERT


On Mon, Apr 13, 2020 at 12:28 PM Davide Pesavento <davidepesa at gmail.com>
wrote:

> On Mon, Apr 13, 2020 at 8:18 AM Junxiao Shi via Nfd-dev
> <nfd-dev at lists.cs.ucla.edu> wrote:
> >
> > 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.
>

Addressed.


> >
> >
> > Several steps specify MustBeFresh in Interest, but lacks FreshnessPeriod
> in Data. A Data without FreshnessPeriod cannot satisfy an Interest with
> MustBeFresh.
>

Addressed.


> > Given signed Interests are unique, it's unnecessary to include
> MustBeFresh.
>

Let's still keep it.


> >
> >
> > 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.
>
> I would NOT recommend to restrict ourselves to ASCII, it's 2020...
>
> > CA profile packet should have FinalBlockId (set to the same as last name
> component), so that it is compatible with segmentation convention.
>

Added.


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

Fixed.


> >
> >
> > 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:
> >
> > derive bits from ECDH
> > import bits as HKDF key
>

I assume the bits are used as HKDF IKM as defined in
https://tools.ietf.org/html/rfc5869#section-2.2.


> > 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.
>
> I'm not sure why this needs to be specified. The ECDH shared secret is
> normally the X coordinate of the calculated point, i.e. 32 bytes with
> NIST P-256. By saying that one must run HKDF with the ECDH shared
> secret as input, it's pretty obvious that you use the entire secret,
> nothing more, nothing less. I don't think there's any ambiguity here.
>
> >
> >
> > 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.
>

Addressed.

Best,
Zhiyi


> > 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);
> > }
> >
> > _______________________________________________
> > Nfd-dev mailing list
> > Nfd-dev at lists.cs.ucla.edu
> > http://www.lists.cs.ucla.edu/mailman/listinfo/nfd-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.lists.cs.ucla.edu/pipermail/nfd-dev/attachments/20200413/9729d5cb/attachment.html>


More information about the Nfd-dev mailing list