The digest function of the Crypto module's Hash object fails encoding hash in utf16le encoding

  • Version: v6.17.1, v8.16.1, v10.16.3, and v12.11.0
  • Platform: Linux msi 4.15.0-62-generic [insert hashtag here]69-Ubuntu SMP Wed Sep 4 20:55:53 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
  • Subsystem: crypto

Issue

According to the documentation the digest function on a Hash object, the encoding parameter should support the utf16le and ucs2 encodings.

When creating a sha256 hash using crypto's createHash function, the resulting hash object can't be digested into these encodings.

Instead an Error [ERR_CRYPTO_HASH_DIGEST_NO_UTF16] is thrown.

How to reproduce using the interpreter

v6.17.1
  1. Create a sha256 hash object
> let hash = crypto.createHash('sha256')
undefined
  1. Feed it some data
> hash.update('test')
Hash {
  _handle: {},
  _options: undefined,
  writable: true,
  readable: true }
  1. Try digest using utf16le as encoding (same error occurs for ucs2 which is an alias for utf16le)
> hash.digest('utf16le')
Error: hash.digest() does not support UTF-16
    at Error (native)
    at Hash.digest (crypto.js:83:23)
    at repl:1:6
    at sigintHandlersWrap (vm.js:22:35)
    at sigintHandlersWrap (vm.js:73:12)
    at ContextifyScript.Script.runInThisContext (vm.js:21:12)
    at REPLServer.defaultEval (repl.js:340:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:539:10)
v8.16.1
  1. Create a sha256 hash object
> let hash = crypto.createHash('sha256')
undefined
  1. Feed it some data
> hash.update('test')
Hash {
  _handle: {},
  _options: undefined,
  writable: true,
  readable: true }
  1. Try digest using utf16le as encoding (same error occurs for ucs2 which is an alias for utf16le)
> hash.digest('utf16le')
Error: hash.digest() does not support UTF-16
    at Hash.digest (crypto.js:107:23)
v10.16.3
  1. Create a sha256 hash object
> let hash = crypto.createHash('sha256')
undefined
  1. Feed it some data
> hash.update('test')
Hash {
  _handle: {},
  _options: undefined,
  writable: true,
  readable: true,
  [Symbol(kState)]: { [Symbol(kFinalized)]: false } }
  1. Try digest using utf16le as encoding (same error occurs for ucs2 which is an alias for utf16le)
> hash.digest('utf16le')
Thrown:
Error [ERR_CRYPTO_HASH_DIGEST_NO_UTF16]: hash.digest() does not support UTF-16
    at Hash.digest (internal/crypto/hash.js:74:11)
v12.11.0
  1. Create a sha256 hash object
> let hash = crypto.createHash('sha256')
undefined
  1. Feed it some data
> hash.update('test')
Hash {
  _options: undefined,
  writable: true,
  readable: true,
  [Symbol(kHandle)]: {},
  [Symbol(kState)]: { [Symbol(kFinalized)]: false }
}
  1. Try digest using utf16le as encoding (same error occurs for ucs2 which is an alias for utf16le)
> hash.digest('utf16le')
Thrown:
Error [ERR_CRYPTO_HASH_DIGEST_NO_UTF16]: hash.digest() does not support UTF-16
    at Hash.digest (internal/crypto/hash.js:89:11)
    at repl:1:6
    at Script.runInThisContext (vm.js:126:20)
    at REPLServer.defaultEval (repl.js:401:29)
    at bound (domain.js:420:14)
    at REPLServer.runBound [as eval] (domain.js:433:12)
    at REPLServer.onLine (repl.js:717:10)
    at REPLServer.emit (events.js:215:7)
    at REPLServer.EventEmitter.emit (domain.js:476:20)
    at REPLServer.Interface._onLine (readline.js:316:10)

Expected output: 蚟臐䲈敽⾚ꃪ嫅ᗐ뾣᭏ଫⲂ巑ᕬࠊ

Additional notes

Yup, it makes little to no sense encoding your hash using this encoding, but it's a documented feature after all. 🤷‍♂️