ワンタイム パスワード (OTP) は、さまざまなアプリケーションやサービスで認証と検証の目的で広く使用されています。通常、サーバーがそれらを生成し、SMS、電子メール、またはその他のチャネル経由でユーザーに送信します。次に、ユーザーは OTP を入力して身元を確認するか、アクションを実行します。
Node JS で OTP ベースの検証を実装する必要があるタスクを受け取りました。このようなものを統合する前に、私たちのほとんどの開発者/エンジニアは、インターネットでベスト プラクティス、チュートリアル、最近の技術トレンド、他の主要なソフトウェア システムが実装中に直面する問題などを調べていると思います。そこで私はそれを実行しましたが、最も注目を集めたのは、OTP を生成することだけが機能する otp-lib や otp-generator のようなライブラリでした。 SMS や電子メールでの送信などの残りのタスクは、引き続き他の手段で行う必要があります。このようなライブラリが存在することを知った後で頭に浮かぶ最初の疑問は、ワンライナーを書くだけで済むのに、なぜわざわざライブラリを使用して OTP を生成する必要があるのかということです。
const otp = Math.ceil(Math.random() * 10000)
このブログ投稿では、OTP ジェネレーターの小規模な研究中に学んだこと、OTP を生成するために Math.random() を使用するのがなぜ悪い考えなのか、OTP を生成する他の方法は何か、ライブラリを使用する理由について説明します。このようなタスクに使用する必要がありますか?
乱数の種類
乱数には主に 2 種類があります:
- 擬似乱数 (PRN)
- 暗号化乱数 (CRN)。
擬似乱数
擬似乱数は、シードと呼ばれる初期値を取得し、ランダムに見える一連の数値を生成するアルゴリズムによって生成されます。ただし、アルゴリズムは決定論的です。つまり、シードとアルゴリズムがわかっていれば、シーケンス内の次の数値を予測できます。 Javascript の Math.random() と Python のrandom.randInt() は、擬似乱数生成器の例です。
暗号乱数
暗号乱数は、予測不可能なプロセスによって生成され、再現したり推測したりすることはできません。これらは通常、大気騒音、熱雑音、量子効果などの物理現象に基づいています。
Math.random() はどのように機能するのでしょうか?
Javascript エンジンが異なると、乱数を生成する際の動作が少し異なりますが、基本的にはすべて単一のアルゴリズム XorShift128+ によって決まります。
XorShift は決定論的アルゴリズムであり、高速な非線形変換ソリューションとして加算を使用します。乗算を使用する他のアルゴリズムと比較して、このアルゴリズムは高速です。また、メルセンヌ ツイスター (Python のランダム モジュールで使用) よりも失敗する可能性が低くなります
アルゴリズムは 2 つの状態変数を受け取り、XOR とシフトを適用して、更新された状態変数の合計を整数で返します。通常、状態はシステム クロックを使用してシードされます。これは、システム クロックが一意の番号の優れたソースであるためです。
JavaScript での XOR シフト プラスの実装は次のようになります:
let state0 = 1; let state1 = 2; function xorShiftPlus() { let s1 = state0; let s0 = state1; state0 = s0; s1 ^= s1 > 17; s1 ^= s0; s1 ^= s0 >> 26; state1 = s1; return state0 + state1; }
返された整数は、定数との OR 演算を使用して double に変換されます。詳細な実装は、Chrome ソース コードで確認できます。
Math.random() で生成された乱数を予測する方法
Math.random() の結果を予測するのは困難ですが、完全に不可能というわけではありません。アルゴリズムを理解していれば、state0 と state1 の値がわかっていれば、同じ乱数を簡単に再生成できます。
XorShift128+ のリバース エンジニアリング Z3 定理証明器を使用すると、サーバーによって生成された 3 つの連続する乱数を提供することで、state0 と state1 の値を見つけることができます。
Z3 ソルバーの実装はここにあります。
ここで問題は、これら 3 つの乱数をサーバーから取得する方法です。それが難しい部分ですが、次のような場合に取得できます:
- If an API returns a randomly generated number in its response or headers, it can easily be obtained by sending requests at set intervals.
- API documentation like OpenAPI/Swagger in modern applications is generated on the server. Sometimes their responses can contain an example value that uses a random number.
- With frameworks like NextJS that use server-side rendering while also being capable of handling backend API integrations, there are high chances of getting randomly generated numbers from the content served by them.
Another approach to exploit a random number is using the fact that Math.random() only returns numbers between 0 and 1 with 16 decimal places. This means that there are only 10^16 possible values that Math.random() can return. This is a very small space compared to the space of possible OTPs. if your OTP has 6 digits, there are 10^6 possible values. This visualizer shows that there is a pattern to the numbers generated. Using it, the possibilities can be reduced by 30%. Therefore, if you can guess or brute-force some of the digits of the OTP, you can reduce the space of possible values and increase your chances of finding the correct OTP.
Generating a Cryptographic Random Number in NodeJS
As mentioned previously, cryptographic random numbers are non-deterministic because they depend on the physical factors of a system. Every programming language can access those factors using low-level OS kernel calls.
NodeJS provides its inbuilt crypto module, which we can use to generate randomBytes and then convert them to a number. These random bytes are cryptographic and purely random in nature. The generated number can easily be truncated to the exact number of digits we want in OTP.
import * as crypto from 'crypto'; const num = parseInt(crypto.randomBytes(3).toString('hex'), 16) // num.toString().slice(0,4) // truncate to 4 digits
NodeJS 14.10+ provides another function from crypto to generate a random number in a given min-max range.
crypto.randomInt(1001, 9999)
Even after knowing the vulnerability of Math.random() and finding a more secure way to generate a random number cryptographically, we still remain with the same question from the beginning. Why do we have to go to such lengths to use a library to generate OTP when all we have to do is write a one-liner?
Before answering this questions, let's take a look at what is the inconvenience faced while handling and storing an OTP. The problem with using the above method to generate OTPs is that you have to store them in the database in order to verify them later. Storing the OTP in the database is not a good practice for the following reasons:
- Storing OTPs in the database creates a lot of garbage data that has to be cleaned up periodically. OTP means a one-time password that can expire after a single use. It can also expire if not used for a specific duration or a new OTP is requested without using the previous one. This mainly adds unnecessary overhead to the database operations for maintaining valid OTPs while also consuming storage space.
- Storing OTPs in the database poses a security risk if the database is compromised. An attacker who gains access to the database can read the OTPs and use them to bypass the authentication or verification process. This can lead to account takeover, identity theft, or fraud.
- Storing OTPs in the database makes them vulnerable to replay attacks. A replay attack is when an attacker intercepts an incoming valid OTP and uses it again before it expires. This can allow the attacker to perform unauthorised actions or access sensitive information.
What do the OTP libraries do differently?
The OTP libraries use different algorithms and techniques to generate and verify OTPs that behave similarly to a Cryptographic random OTP, while also removing the overhead to store the OTP in a database.
There are mainly two types of OTP implementation techniques.
HOTP
HOTP stands for HMAC-based One-Time Password. It is an algorithm that generates an OTP based on a secret key and a counter. The secret key is a random string that is shared between the server and the user. The counter is an integer that increments every time an OTP is generated or verified.
The algorithm works as follows:
• The server and the user generate the same OTP by applying a cryptographic hash function, such as SHA-1, to the concatenation of the secret key and the counter.
• The server and the user truncate the hash value to obtain a fixed-length OTP, usually 6 or 8 digits.
• The user sends the OTP to the server for verification.
• The server compares the OTP with its own generated OTP and verifies it if they match.
• The server and the user increment their counters by one.
HOTP は、Yubikey などのハードウェア トークン ベースの認証で主に使用されます。 Yubikey は基本的に、コンピュータまたは電話に物理的に接続できるプログラムされたハードウェア キーです。 SMS や電子メールからコードを受け取る代わりに、Yubikey のボタンを押すだけで本人確認と認証を行うことができます。
HOTP の利点は次のとおりです。
• OTP はその場で生成および検証できるため、データベースに保存する必要はありません。
• 予測不可能かつ不可逆的な暗号化ハッシュ関数を使用するため、疑似乱数に依存しません。
• 各 OTP は 1 回だけ有効であるため、リプレイ攻撃に耐性があります。
HOTP の欠点は次のとおりです。
• サーバーとユーザーのカウンター間の同期が必要です。ネットワークの遅延、送信エラー、デバイスの紛失などにより同期が取れていない場合、検証は失敗します。
• 新たに生成された HOTP が使用されない限り有効ですが、脆弱性となる可能性があります。
• 秘密鍵を配布および保管するには安全な方法が必要です。秘密キーが漏洩または盗難された場合、OTP が侵害される可能性があります。
TOTP
TOTP は、タイムベースのワンタイム パスワードの略です。これは、秘密キー、タイムスタンプ、エポックに基づいて OTP を生成するアルゴリズムです。
- 秘密キーは、サーバーとユーザーの間で共有されるランダムな文字列です。 SHA1( "secretvalue" + user_id ) を生成することで、ユーザーごとに一意に作成できます。
- タイムスタンプは、現在時刻を秒単位で表す整数です
- エポックとは、アルゴリズムが同じ結果を生成する期間です。一般に、30 秒から 1 分の間に保持されます。
アルゴリズムは次のように機能します:
• サーバーはユーザーの秘密キーを決定し、Authenticator アプリなどの媒体を介してそれを共有します。
• サーバーは OTP を直接生成し、メールまたは SMS でユーザーに送信することも、オーセンティケーターを使用して共有キーを使用して OTP を生成するようにユーザーに要求することもできます。
• ユーザーは、メールまたは SMS で受信した OTP を直接送信することも、2FA の場合は一定の時間枠で認証アプリで OTP を生成することもできます。
• サーバーは OTP を独自に生成した OTP と比較し、それらがエポック時間範囲内で十分に近いかどうかを検証します。
TOTP の利点は次のとおりです。
• OTP はその場で生成および検証できるため、データベースに保存する必要はありません。
• 予測不可能かつ不可逆的な暗号化ハッシュ関数を使用するため、疑似乱数に依存しません。
• 各 OTP は短期間のみ有効であるため、リプレイ攻撃に対して耐性があります。
• サーバーとユーザーのタイムスタンプ間の同期は必要ありません。適度に正確なクロックを持っている限り、OTP を独立して生成および検証できます。
TOTP の欠点は次のとおりです。
• 秘密鍵を配布および保存するには安全な方法が必要です。秘密キーが漏洩または盗難された場合、OTP が侵害される可能性があります。
• サーバーとユーザーの両方にとって信頼できる時間源が必要です。時計が歪んでいたり改ざんされている場合、検証は失敗します。
• サーバーはリクエストの処理における時間のずれや遅延を考慮する必要があるため、クライアントよりもわずかに長いエポックを維持する必要があります。
結論
OTP に関するちょっとした調査を通じて、Math.random() が予測、悪用、再生できることを知りました。また、OTP をデータベースに保存するのは良い習慣ではないこともわかりました。
TOTP は安全で効率的な OTP を生成し、検証することもできます。オンラインだけでなくオフラインでも OTP を生成でき、同期やストレージを必要とせず、リプレイ攻撃に耐性があります。したがって、ベスト プラクティス、セキュリティ、信頼性に関する懸念のほとんどが解決されます。
以上がMath.random() を実行するだけで済むのに、なぜ OTP ライブラリを使用するのでしょうか。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

JavaScriptは、最新のブラウザにすでに組み込まれているため、インストールを必要としません。開始するには、テキストエディターとブラウザのみが必要です。 1)ブラウザ環境では、タグを介してHTMLファイルを埋め込んで実行します。 2)node.js環境では、node.jsをダウンロードしてインストールした後、コマンドラインを介してJavaScriptファイルを実行します。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

WebStorm Mac版
便利なJavaScript開発ツール

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

メモ帳++7.3.1
使いやすく無料のコードエディター
