Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@epic-web/totp

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@epic-web/totp - npm Package Compare versions

Comparing version 1.0.6 to 1.1.0

11

index.d.ts

@@ -12,12 +12,14 @@ /**

* SHA1.
* @param {string} [options.charSet='0123456789'] - The character set to use, defaults to the numbers 0-9.
* @param {string} [options.secret] The secret to use for the TOTP. It should be
* base32 encoded (you can use https://npm.im/thirty-two). Defaults to a random
* secret: base32.encode(crypto.randomBytes(10)).toString().
* @returns {{otp: string, secret: string, period: number, digits: number, algorithm: string}}
* @returns {{otp: string, secret: string, period: number, digits: number, algorithm: string, charSet: string}}
* The OTP, secret, and config options used to generate the OTP.
*/
export function generateTOTP({ period, digits, algorithm, secret, }?: {
export function generateTOTP({ period, digits, algorithm, secret, charSet, }?: {
period?: number;
digits?: number;
algorithm?: string;
charSet?: string;
secret?: string;

@@ -30,2 +32,3 @@ }): {

algorithm: string;
charSet: string;
};

@@ -66,2 +69,3 @@ /**

* @param {string} [options.algorithm] The algorithm to use.
* @param {string} [options.charSet] - The character set to use, defaults to the numbers 0-9.
* @param {number} [options.window] The number of OTPs to check before and after

@@ -74,3 +78,3 @@ * the current OTP. Defaults to 1.

*/
export function verifyTOTP({ otp, secret, period, digits, algorithm, window, }: {
export function verifyTOTP({ otp, secret, period, digits, algorithm, charSet, window, }: {
otp: string;

@@ -81,2 +85,3 @@ secret: string;

algorithm?: string;
charSet?: string;
window?: number;

@@ -83,0 +88,0 @@ }): {

@@ -17,2 +17,3 @@ /**

const DEFAULT_ALGORITHM = 'SHA1'
const DEFAULT_CHAR_SET = '0123456789'
const DEFAULT_DIGITS = 6

@@ -34,2 +35,3 @@ const DEFAULT_WINDOW = 1

* HOTP. Defaults to 'SHA1'.
* @param {string} [options.charSet='0123456789'] - The character set to use, defaults to the numbers 0-9.
* @returns {string} The generated HOTP.

@@ -39,3 +41,8 @@ */

secret,
{ counter = 0, digits = DEFAULT_DIGITS, algorithm = DEFAULT_ALGORITHM } = {}
{
counter = 0,
digits = DEFAULT_DIGITS,
algorithm = DEFAULT_ALGORITHM,
charSet = DEFAULT_CHAR_SET,
} = {}
) {

@@ -47,9 +54,15 @@ const byteCounter = Buffer.from(intToBytes(counter))

const offset = hashBytes[19] & 0xf
let hotp =
(((hashBytes[offset] & 0x7f) << 24) |
((hashBytes[offset + 1] & 0xff) << 16) |
((hashBytes[offset + 2] & 0xff) << 8) |
(hashBytes[offset + 3] & 0xff)) +
''
return hotp.slice(-digits)
let hotpVal =
((hashBytes[offset] & 0x7f) << 24) |
((hashBytes[offset + 1] & 0xff) << 16) |
((hashBytes[offset + 2] & 0xff) << 8) |
(hashBytes[offset + 3] & 0xff)
let hotp = ''
for (let i = 0; i < digits; i++) {
hotp += charSet.charAt(hotpVal % charSet.length)
hotpVal = Math.floor(hotpVal / charSet.length)
}
return hotp
}

@@ -70,2 +83,3 @@

* HOTP. Defaults to 'SHA1'.
* @param {string} [options.charSet='0123456789'] - The character set to use, defaults to the numbers 0-9.
* @param {number} [options.window=1] - The number of counter values to check

@@ -84,2 +98,3 @@ * before and after the current counter value. Defaults to 1.

algorithm = DEFAULT_ALGORITHM,
charSet = DEFAULT_CHAR_SET,
window = DEFAULT_WINDOW,

@@ -89,3 +104,5 @@ } = {}

for (let i = counter - window; i <= counter + window; ++i) {
if (generateHOTP(secret, { counter: i, digits, algorithm }) === otp) {
if (
generateHOTP(secret, { counter: i, digits, algorithm, charSet }) === otp
) {
return { delta: i - counter }

@@ -108,6 +125,7 @@ }

* SHA1.
* @param {string} [options.charSet='0123456789'] - The character set to use, defaults to the numbers 0-9.
* @param {string} [options.secret] The secret to use for the TOTP. It should be
* base32 encoded (you can use https://npm.im/thirty-two). Defaults to a random
* secret: base32.encode(crypto.randomBytes(10)).toString().
* @returns {{otp: string, secret: string, period: number, digits: number, algorithm: string}}
* @returns {{otp: string, secret: string, period: number, digits: number, algorithm: string, charSet: string}}
* The OTP, secret, and config options used to generate the OTP.

@@ -120,2 +138,3 @@ */

secret = base32.encode(crypto.randomBytes(10)).toString(),
charSet = DEFAULT_CHAR_SET,
} = {}) {

@@ -126,5 +145,6 @@ const otp = generateHOTP(base32.decode(secret), {

algorithm,
charSet,
})
return { otp, secret, period, digits, algorithm }
return { otp, secret, period, digits, algorithm, charSet }
}

@@ -181,2 +201,3 @@

* @param {string} [options.algorithm] The algorithm to use.
* @param {string} [options.charSet] - The character set to use, defaults to the numbers 0-9.
* @param {number} [options.window] The number of OTPs to check before and after

@@ -195,2 +216,3 @@ * the current OTP. Defaults to 1.

algorithm,
charSet,
window = DEFAULT_WINDOW,

@@ -203,2 +225,3 @@ }) {

algorithm,
charSet,
})

@@ -205,0 +228,0 @@ }

@@ -14,3 +14,3 @@ {

},
"version": "1.0.6",
"version": "1.1.0",
"description": "Create and verify cryptographically secure Time-based One-time Passwords (TOTP) using the HMAC-based One-time Password (HOTP) algorithm.",

@@ -17,0 +17,0 @@ "main": "index.js",

@@ -32,3 +32,3 @@ <div>

[![Build Status][build-badge]][build]
[![GPL 3.0 License][license-badge]][license]
[![MIT License][license-badge]][license]
[![Code of Conduct][coc-badge]][coc]

@@ -84,3 +84,3 @@ <!-- prettier-ignore-end -->

const { secret, period, digits, algorithm } = generateTOTP()
const uri = getTOTPAuthUri({
const otpUri = getTOTPAuthUri({
period,

@@ -157,2 +157,55 @@ digits,

## Customizable Character Set for Increased Security
### Why Charset Matters
When it comes to security, every bit of entropy counts. Entropy measures the
unpredictability and in turn the security of your OTPs. The traditional TOTP
setup often employs a 6-digit numerical code, providing a million (10^6)
combinations. This is the default behaviour for this implementation. While that
is robust, there's room for improvement.
By introducing a customizable character set feature, you can exponentially
increase the entropy of the OTPs, making them much more secure against
brute-force attacks. For example, if you extend your character set to include 26
uppercase letters and 10 digits, a 6-character OTP would have 36^6 = 2.1 billion
combinations. When paired with rate-limiting mechanisms, this configuration
becomes practically impervious to brute-force attacks.
### Potential for Main Form of Authentication
With this added complexity, TOTPs can, in theory, be used as the primary form of
authentication, rather than just a second factor. This is particularly useful
for applications requiring heightened security.
### Usage with Custom Character Set
In addition to the existing options, you can specify a charSet in both
`generateTOTP` and `verifyTOTP`.
Here's how you can generate an OTP with a custom character set:
```js
import { generateTOTP, verifyTOTP } from '@epic-web/totp'
const { otp, secret, period, digits, algorithm, charSet } = generateTOTP({
charSet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', // custom character set
})
// Remember to save the charSet to your database as well.
// To verify
const isValid = verifyTOTP({
otp,
secret,
period,
digits,
algorithm,
charSet,
})
```
Just as an aside, you probably want to exclude the letter O and the number 0 to
make it easier for users to enter the code.
## API

@@ -180,3 +233,4 @@

* secret: base32.encode(crypto.randomBytes(10)).toString().
* @returns {{otp: string, secret: string, period: number, digits: number, algorithm: string}}
* @param {string} [options.charSet='0123456789'] - The character set to use, defaults to the numbers 0-9.
* @returns {{otp: string, secret: string, period: number, digits: number, algorithm: string, charSet: string}}
* The OTP, secret, and config options used to generate the OTP.

@@ -200,2 +254,3 @@ */

* @param {string} [options.algorithm] The algorithm to use.
* @param {string} [options.charSet] The character set to use, defaults to the numbers 0-9.
* @param {number} [options.window] The number of OTPs to check before and after

@@ -237,3 +292,3 @@ * the current OTP. Defaults to 1.

[build]: https://github.com/epicweb-dev/totp/actions?query=workflow%3Arelease
[license-badge]: https://img.shields.io/badge/license-GPL%203.0%20License-blue.svg?style=flat-square
[license-badge]: https://img.shields.io/badge/license-MIT%20License-blue.svg?style=flat-square
[license]: https://github.com/epicweb-dev/totp/blob/main/LICENSE

@@ -240,0 +295,0 @@ [coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc