diff --git a/doc/api/crypto.md b/doc/api/crypto.md
index 8e0e37e5fedb3a..4228abd800fd38 100644
--- a/doc/api/crypto.md
+++ b/doc/api/crypto.md
@@ -3630,7 +3630,7 @@ changes:
* `options`: {Object}
* `length`: {number} The bit length of the key to generate. This must be a
value greater than 0.
- * If `type` is `'hmac'`, the minimum is 1, and the maximum length is
+ * If `type` is `'hmac'`, the minimum is 8, and the maximum length is
231-1. If the value is not a multiple of 8, the generated
key will be truncated to `Math.floor(length / 8)`.
* If `type` is `'aes'`, the length must be one of `128`, `192`, or `256`.
@@ -3902,7 +3902,7 @@ added: v15.0.0
accepted values are `'hmac'` and `'aes'`.
* `options`: {Object}
* `length`: {number} The bit length of the key to generate.
- * If `type` is `'hmac'`, the minimum is 1, and the maximum length is
+ * If `type` is `'hmac'`, the minimum is 8, and the maximum length is
231-1. If the value is not a multiple of 8, the generated
key will be truncated to `Math.floor(length / 8)`.
* If `type` is `'aes'`, the length must be one of `128`, `192`, or `256`.
diff --git a/lib/internal/crypto/keygen.js b/lib/internal/crypto/keygen.js
index c6909b227d0c15..a2dad1154f0c41 100644
--- a/lib/internal/crypto/keygen.js
+++ b/lib/internal/crypto/keygen.js
@@ -349,7 +349,7 @@ function generateKeyJob(mode, keyType, options) {
const { length } = options;
switch (keyType) {
case 'hmac':
- validateInteger(length, 'options.length', 1, 2 ** 31 - 1);
+ validateInteger(length, 'options.length', 8, 2 ** 31 - 1);
break;
case 'aes':
validateOneOf(length, 'options.length', kAesKeyLengths);
diff --git a/test/parallel/test-crypto-secret-keygen.js b/test/parallel/test-crypto-secret-keygen.js
index 0739393643d6bb..0bd45f653e46d2 100644
--- a/test/parallel/test-crypto-secret-keygen.js
+++ b/test/parallel/test-crypto-secret-keygen.js
@@ -51,6 +51,14 @@ assert.throws(() => generateKey('hmac', { length: -1 }, common.mustNotCall()), {
code: 'ERR_OUT_OF_RANGE'
});
+assert.throws(() => generateKey('hmac', { length: 4 }, common.mustNotCall()), {
+ code: 'ERR_OUT_OF_RANGE'
+});
+
+assert.throws(() => generateKey('hmac', { length: 7 }, common.mustNotCall()), {
+ code: 'ERR_OUT_OF_RANGE'
+});
+
assert.throws(
() => generateKey('hmac', { length: 2 ** 31 }, common.mustNotCall()), {
code: 'ERR_OUT_OF_RANGE'
@@ -60,6 +68,14 @@ assert.throws(() => generateKeySync('hmac', { length: -1 }), {
code: 'ERR_OUT_OF_RANGE'
});
+assert.throws(() => generateKeySync('hmac', { length: 4 }), {
+ code: 'ERR_OUT_OF_RANGE'
+});
+
+assert.throws(() => generateKeySync('hmac', { length: 7 }), {
+ code: 'ERR_OUT_OF_RANGE'
+});
+
assert.throws(
() => generateKeySync('hmac', { length: 2 ** 31 }), {
code: 'ERR_OUT_OF_RANGE'