Skip to content
New issue

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

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

Already on GitHub? Sign in 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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