ipfs-social-proof icon indicating copy to clipboard operation
ipfs-social-proof copied to clipboard

[API] ASCII armor for signatures & pub keys

Open daviddahl opened this issue 6 years ago • 3 comments

edit Looks like a lot of this issue is confusion of key types and not understanding all formats

I have spent a little bit of time figuring out the round trip of RSAPubKey -> Uint8Array -> 'base64' string.

For whatever reason, when TextEncoder - and pretty much all of the base64 -> Uint8Array Array libraries I have found on npm, the returned Uint8Array has the wrong prototype (TypedArray) or the Uint8Array is too short (288 vs 299 length).

I kind of think there is a base64 encoder/ decoder inside IPFS code somewhere, I just have not found it yet.

In the mean time I have declared the public keys as Dehydrated Public Keys and they are merely created like this: plaintext = JSON.stringify([Uint8Array] rsaKeyBytes)

daviddahl avatar Oct 13 '18 23:10 daviddahl

I pulled in node-forge directly to use the pki and pem modules. Will need to keep this open to figure out ASCII armor of signatures next

daviddahl avatar Oct 17 '18 00:10 daviddahl

My latest discovery is that - even using node-forge when one converts the ascii armored (PEM) public key back to an RsaPublicKey, the verification fails as the key length is shorter - bytes are lost in the procedure I was using: pki.publicKeyFromPem(pemPubKey)

So to document what I am doing is this:

 get pubKeyDehydrated () {
    // get a base64 encoded marshaled pub key
    const pub = this.node._peerInfo.id._privKey.public
    const mk = this._crypto.keys.marshalPublicKey(pub)
    return this.dehydrate(mk)
}

  dehydrate (buff) {
    let s = JSON.stringify(buff)
    let arr = JSON.parse(s).data
    return JSON.stringify(arr)
}

I get the key's byes and JSON stringify then just keep a stringified array of those bytes. To convert back to an RsaPublicKey:

rehydrate (jsonStr) {
    // re-hydrate a json string back into an Uint8Array
    // expecting a string like so: '{"data": [0,2,5,7,12,34,122...]}'
    const obj = JSON.parse(jsonStr)
    // Get the Uint8Array version of the stringified data (key or signature)
    const buff = Buffer.from(obj)
    return buff
  }

Its totally unconventional... Not ideal, but works - for now. A test suite foir the crypto is need to understand what needs to happen here.

daviddahl avatar Nov 08 '18 13:11 daviddahl

Ok, we now have merged in #52 which handles converting to PEM encoded public key and back to RSA key that can be used for verification

  • [x] JWK -> RSA -> PEM
  • [x] PEM -> RSA
  • [ ] Signature -> PEM
  • [ ] PEM sig -> bytes (buffer)

daviddahl avatar Nov 16 '18 05:11 daviddahl