diff --git a/doc/api/crypto.md b/doc/api/crypto.md
index 38d7134122b68c..639a745266d0f8 100644
--- a/doc/api/crypto.md
+++ b/doc/api/crypto.md
@@ -3584,7 +3584,7 @@ added: v15.0.0
* `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`.
@@ -3851,7 +3851,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 1469a01682edda..5004ad1a4b7680 100644
--- a/lib/internal/crypto/keygen.js
+++ b/lib/internal/crypto/keygen.js
@@ -356,7 +356,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 ab662aeb5d123b..dddb2865bcbbae 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'