Search code examples
node.jsed25519

crypto.generateKeyPairSync('ed25519') does not verify simple test, which an 'ec' keypair verifies without issue. What is the mistake?


Been playing around with the crypto module in Nodejs and using crypto.generateKeyPairSync. When running a short verification test with 'ec' keys, this evaluates as expected, but when testing with 'ed25519' generated keys, this never evaluates to true.

  const crypto = require('crypto')

  let identity = {}

  identity.identifierKeys__ = await crypto.generateKeyPairSync('ec', {
    namedCurve: 'secp256k1', // Options
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem'
    }
  })
  identity.identifierKeys = await crypto.generateKeyPairSync('ed25519', {
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem'
    }
  })
// console.log(identity.identifierKeys)
// test keys
  let key = identity.identifierKeys__ // if i swap to .identifierKeys, never evaluates to true
  let msg = 'testingInformation'
  let v = await crypto.createSign('SHA256')
      v.write(msg)
      v.end()
  let sig = await v.sign(key.privateKey, 'base64')
  let t = await crypto.createVerify('SHA256')
      t.write(msg)
      t.end()
  let r = await t.verify(key.publicKey, sig, 'base64')

  console.log(sig)
  console.log(r)

Solution

  • NodeJS provides two implementations for signing/verifying, the Sign/Verify class (since v0.1.92) and crypto.sign()/crypto.verify() (since v12.0.0).

    Signing and verifying with Ed25519 (and Ed448) is possible with crypto.sign() and crypto.verify():

    ...
    let msg = 'testingInformation'
    var signature = crypto.sign(null, Buffer.from(msg), identity.identifierKeys.privateKey)
    var verified = crypto.verify(null, Buffer.from(msg), identity.identifierKeys.publicKey, signature)
    console.log(signature.toString('base64'))
    console.log(verified)