{"record":{"id":"0b94b6ec668003a6","repo":"denoland/deno","slug":"algorithm-must-be-specified-when-using-non-ed25519","errorCode":null,"errorMessage":"Algorithm must be specified when using non-Ed25519 keys","messagePattern":"Algorithm must be specified when using non-Ed25519 keys","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/sig.ts","lineNumber":439,"sourceCode":"      if (\n        ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, ctx) &&\n        ctx.length > 0\n      ) {\n        throw new TypeError(\"Context parameter is unsupported\");\n      }\n      result = new FastBuffer(114);\n      op_node_sign_ed448(handle, dataBytes, result);\n    } else {\n      let digest = algorithm;\n      if (digest == null) {\n        if (keyType === \"rsa-pss\") {\n          const details = op_node_get_asymmetric_key_details(handle);\n          if (details.hashAlgorithm) {\n            digest = details.hashAlgorithm;\n          }\n        }\n        if (digest == null) {\n          throw new TypeError(\n            \"Algorithm must be specified when using non-Ed25519 keys\",\n          );\n        }\n      }\n      // Preserve padding/saltLength options from the original key\n      const privateKeyObject = new PrivateKeyObject(handle);\n      const signKey = typeof key === \"object\" &&\n          !(ObjectPrototypeIsPrototypeOf(KeyObject.prototype, key))\n        ? { ...key, key: privateKeyObject }\n        : privateKeyObject;\n      result = Sign(digest).update(dataBytes)\n        .sign(signKey);\n    }\n\n    if (callback) {\n      setTimeout(() => callback(null, result));\n    } else {\n      return result;","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/sig.ts#L421-L457","documentation":"One-shot crypto.sign() with a non-Ed25519/Ed448 key requires an explicit digest. The only default is an rsa-pss key whose stored key details include a hashAlgorithm; for every other key type (rsa, ecdsa, dsa, rsa-pss without an embedded hash) algorithm == null throws this TypeError.","triggerScenarios":"crypto.sign(null, data, rsaPrivateKey); crypto.sign(null, data, ecdsaKey); copy-pasted ed25519 example code (which passes null) reused with RSA or EC keys.","commonSituations":"Key-agnostic signing helpers that pass null because it works for ed25519; code written against rsa-pss keys with embedded hashes then pointed at plain RSA keys; WebCrypto ports where the hash was part of the key rather than the call.","solutions":["Pass an explicit digest: crypto.sign(\"sha256\", data, key).","Branch by key.asymmetricKeyType — null only for ed25519/ed448 (and rsa-pss with embedded hash).","When generating rsa-pss keys, set hashAlgorithm so the embedded default applies."],"exampleFix":"// before\nconst sig = crypto.sign(null, data, key); // throws for RSA/ECDSA keys\n\n// after\nconst alg = key.asymmetricKeyType === \"ed25519\" || key.asymmetricKeyType === \"ed448\" ? null : \"sha256\";\nconst sig = crypto.sign(alg, data, key);","handlingStrategy":"validation","validationCode":"function requiredDigest(key, requested) {\n  if (requested != null) return requested;\n  const t = key.asymmetricKeyType ?? key.key?.asymmetricKeyType;\n  if (t === \"ed25519\" || t === \"ed448\") return null;\n  throw new Error(`an explicit digest (e.g. \"sha256\") is required for ${t} keys`);\n}\nconst sig = crypto.sign(requiredDigest(key, alg), data, key);","typeGuard":"const needsExplicitDigest = (key) => {\n  const t = key.asymmetricKeyType ?? key.key?.asymmetricKeyType;\n  return t !== \"ed25519\" && t !== \"ed448\" && t !== \"rsa-pss\"; // rsa-pss may carry its own hash\n};","tryCatchPattern":"try {\n  sig = crypto.sign(digest, data, key);\n} catch (e) {\n  if (e instanceof TypeError && /Algorithm must be specified/.test(e.message)) {\n    throw new Error(`digest required for key type ${key.asymmetricKeyType}`);\n  }\n  throw e;\n}","preventionTips":["Only pass null for ed25519/ed448 (or rsa-pss keys generated with an embedded hashAlgorithm).","Centralize the key-type-to-digest mapping in one function used by both sign paths.","When generating rsa-pss keys, always set hashAlgorithm so a sensible default exists."],"tags":["crypto","signing","digest","algorithm-required"],"backgroundTag":"missing-digest-algorithm","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}