Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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

Closed
Craphtex opened this issue Oct 1, 2019 · 3 comments
Labels
crypto Issues and PRs related to the crypto subsystem.

Comments

@Craphtex
Copy link

Craphtex commented Oct 1, 2019

  • 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. 🤷‍♂️

@Craphtex
Copy link
Author

Craphtex commented Oct 1, 2019

I would expect this test case to work

const encodeUsingDigest = crypto.createHash('sha256')
                                .update('test')
                                .digest('utf16le')
const encodeUsingBuffer = crypto.createHash('sha256')
                                .update('test')
                                .digest()
                                .toString('utf16le')

assert(encodeUsingDigest === encodeUsingBuffer)

@addaleax addaleax added the crypto Issues and PRs related to the crypto subsystem. label Oct 1, 2019
@addaleax
Copy link
Member

addaleax commented Oct 1, 2019

Thanks for opening an issue! The restriction had historical reasons but is unnecessary now. I’ll open a PR to remove it.

addaleax added a commit to addaleax/node that referenced this issue Oct 1, 2019
Since 71f633a, this is no longer necessary.

Refs: nodejs#22622
Fixes: nodejs#29793
@Craphtex
Copy link
Author

Craphtex commented Oct 2, 2019

Yay thanks, soon we'll be able to accompanying our literally random values with almost as random characters. 😄

@Trott Trott closed this as completed in 389969e Oct 3, 2019
BridgeAR pushed a commit that referenced this issue Oct 9, 2019
Since 71f633a, this is no longer necessary.

Refs: #22622
Fixes: #29793

PR-URL: #29795
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: David Carlier <devnexen@gmail.com>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
crypto Issues and PRs related to the crypto subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants