Skip to content

allow passing a $secretSize when generating a secret#204

Closed
browner12 wants to merge 1 commit intoSpomky-Labs:11.3.xfrom
browner12:AB-set-secret-size
Closed

allow passing a $secretSize when generating a secret#204
browner12 wants to merge 1 commit intoSpomky-Labs:11.3.xfrom
browner12:AB-set-secret-size

Conversation

@browner12
Copy link
Contributor

Target branch: 11.3.x
Resolves issue: none

  • It is a Bug fix
  • It is a New feature
  • Breaks BC
  • Includes Deprecations

this will allow the user to set their own secret length, but allow the package to still handle the creation of the string. I think this is a better interface for the user, as this is most likely a large chunk of the reasons someone would want to have a custom secret over the default.

It also helps avoid a (likely) implicit dependency in user code. We are currently using TOTP::createFromSecret(Base32::encode(Str::random(16)))->getSecret() to generate a shorter random secret than the default. Here we are using the Base32 class from ParagonIE, even though it is not an explicit dependency in our code. We probably should be, rather than implicitly depend on it. I'm guessing other people may make this mistake as well.

If there's a better architecture way to handle this, open to suggestions.

this will allow the user to set their own secret length, but allow the package to still handle the creation of the string.  I think this is a better interface for the user, as this is most likely a large chunk of the reasons someone would want to have a custom secret over the default.

It also helps avoid a (likely) implicit dependency in user code. We are currently using `TOTP::createFromSecret(Base32::encode(Str::random(16)))->getSecret()` to generate a shorter random secret than the default. Here we are using the `Base32` class from `ParagonIE`, even though it is not an explicit dependency in our code. We probably should be, rather than implicitly depend on it. I'm guessing other people may make this mistake as well.
@Spomky
Copy link
Member

Spomky commented Jun 12, 2024

Hi,

Many thanks for the suggestion.
However, I do not see any benefits between the existing creation method TOTP::createFromSecret(random_bytes(16)); and TOTP::generate(16); except the line size (not so long to me).

@browner12
Copy link
Contributor Author

the benefit is the user is not responsible for how the string is generated, only the string length they desire. in the example you give you are passing random_bytes(16), which completely misses out on the Base32::encodeUpper() portion of the default string generation.

@Spomky Spomky self-assigned this Jan 3, 2026
@Spomky Spomky added this to the 11.4.0 milestone Jan 3, 2026
Spomky added a commit that referenced this pull request Jan 3, 2026
This change allows users to specify a custom secret size when generating OTP instances, addressing the limitation mentioned in #204.

Changes:
- Add optional `secretSize` parameter to `OTP::generateSecret()` with validation (must be > 0)
- Update `HOTP::generate()` and `HOTP::create()` to accept and pass through `secretSize`
- Update `TOTP::generate()` and `TOTP::create()` to accept and pass through `secretSize`
- Add comprehensive tests for both HOTP and TOTP covering:
  - Default secret size generation
  - Custom secret size generation
  - Invalid secret size validation (0 and negative values)
  - Both `generate()` and `create()` methods

The parameter is optional and defaults to 64 bytes (103 base32 chars) to maintain backward compatibility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Spomky pushed a commit that referenced this pull request Jan 3, 2026
This allows users to set their own secret length while letting the package handle the creation of the string. This provides a better interface for users and avoids requiring them to know about Base32 encoding.

Changes:
- Add optional `secretSize` parameter to `OTP::generateSecret()` with proper validation (must be > 0)
- Update `HOTP::generate()` and `HOTP::create()` to accept and pass through `secretSize`
- Update `TOTP::generate()` and `TOTP::create()` to accept and pass through `secretSize`
- Use correct type hint `?int $secretSize = null` instead of `int $secretSize = null`
- Add comprehensive tests for both HOTP and TOTP covering:
  - Default secret size generation
  - Custom secret size generation
  - Invalid secret size validation (0 and negative values)
  - Both `generate()` and `create()` methods

The parameter is optional and defaults to 64 bytes (103 base32 chars) to maintain full backward compatibility.

Closes #204
@Spomky Spomky closed this in #249 Jan 3, 2026
@Spomky
Copy link
Member

Spomky commented Jan 3, 2026

Thank you for this contribution! Your feature has been implemented and merged in #249.

The PR includes:

  • Your original implementation for custom secret size
  • Type hint corrections (?int instead of int = null)
  • Validation to ensure secretSize > 0
  • 10 comprehensive tests for both HOTP and TOTP
  • Full backward compatibility

The feature is now available in the 11.4.x branch. Thanks again for identifying this need and providing the initial implementation!

@browner12 browner12 deleted the AB-set-secret-size branch January 5, 2026 15:59
anthonyryan1 pushed a commit to anthonyryan1/otphp that referenced this pull request Jan 8, 2026
* Allow passing a custom secret size when generating OTP

This allows users to set their own secret length while letting the package handle the creation of the string. This provides a better interface for users and avoids requiring them to know about Base32 encoding.

Changes:
- Add optional `secretSize` parameter to `OTP::generateSecret()` with proper validation (must be > 0)
- Update `HOTP::generate()` and `HOTP::create()` to accept and pass through `secretSize`
- Update `TOTP::generate()` and `TOTP::create()` to accept and pass through `secretSize`
- Use correct type hint `?int $secretSize = null` instead of `int $secretSize = null`
- Add comprehensive tests for both HOTP and TOTP covering:
  - Default secret size generation
  - Custom secret size generation
  - Invalid secret size validation (0 and negative values)
  - Both `generate()` and `create()` methods

The parameter is optional and defaults to 64 bytes (103 base32 chars) to maintain full backward compatibility.

Closes Spomky-Labs#204

* Update PHPStan baseline

---------

Co-authored-by: Andrew Brown <browner12@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants