ਆਧੁਨਿਕ ਵੈੱਬ ਸੁਰੱਖਿਆ ਵਿੱਚ ਬੁਨਿਆਦੀ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫਿਕ ਪ੍ਰੋਟੋਕੋਲਾਂ ਵਿੱਚੋਂ, RFC 6238 (TOTP: Time-Based One-Time Password Algorithm) ਆਪਣੀ ਗਣਿਤਕ ਸਾਦਗੀ ਲਈ ਜਾਣਿਆ ਜਾਂਦਾ ਹੈ। ਇਸ ਲਈ ਕਿਸੇ ਇੰਟਰਐਕਟਿਵ ਨੈੱਟਵਰਕ ਹੈਂਡਸ਼ੇਕ, ਕੇਂਦਰੀਕ੍ਰਿਤ ਪਬਲਿਕ ਕੀ ਇਨਫਰਾਸਟ੍ਰਕਚਰ (PKI), ਜਾਂ ਕਲਾਉਡ ਰਾਊਂਡ-ਟ੍ਰਿਪ ਦੀ ਲੋੜ ਨਹੀਂ ਹੁੰਦੀ। ਸਿਰਫ਼ ਇੱਕ ਸਾਂਝੀ Base32 ਗੁਪਤ ਕੁੰਜੀ (Secret Key) ਅਤੇ ਭੌਤਿਕ Unix ਸਮੇਂ ਦੀ ਨਿਰੰਤਰ ਅੱਗੇ ਵਧਦੀ ਚਾਲ ਦੀ ਵਰਤੋਂ ਨਾਲ, ਕਲਾਇੰਟ ਅਤੇ ਸਰਵਰ ਹਰ 30 ਸਕਿੰਟਾਂ ਵਿੱਚ 100% ਗਣਿਤਕ ਸ਼ੁੱਧਤਾ ਨਾਲ ਇੱਕੋ ਜਿਹੇ, ਅਸਥਾਈ 6-ਅੰਕੀ ਪ੍ਰਮਾਣਿਕਤਾ ਟੋਕਨਾਂ ਦੀ ਗਣਨਾ ਕਰਦੇ ਹਨ।
ਇਸ ਵਿਆਪਕ ਗਾਈਡ ਵਿੱਚ, ਅਸੀਂ ਬਲੈਕ-ਬਾਕਸ ਥਰਡ-ਪਾਰਟੀ ਲਾਇਬ੍ਰੇਰੀਆਂ (ਜਿਵੇਂ ਕਿ pyotp ਜਾਂ otplib) ਨੂੰ ਛੱਡ ਕੇ Python, JavaScript, ਅਤੇ Go ਵਿੱਚ ਸ਼ੁਰੂ ਤੋਂ ਸੰਪੂਰਨ RFC 6238 ਕ੍ਰਿਪਟੋਗ੍ਰਾਫਿਕ ਪਾਈਪਲਾਈਨ ਬਣਾਵਾਂਗੇ, ਅਤੇ ਅਧਿਕਾਰਤ IETF ਟੈਸਟ ਵੈਕਟਰਾਂ ਦੇ ਵਿਰੁੱਧ ਹਰੇਕ ਲਾਗੂਕਰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰਾਂਗੇ।
01. ਸਮਾਂ-ਸੰਚਾਲਿਤ ਪ੍ਰਮਾਣਿਕਤਾ ਦੀ ਖ਼ੂਬਸੂਰਤੀ
TOTP ਨੂੰ ਸਮਝਣ ਲਈ, ਸਾਨੂੰ ਪਹਿਲਾਂ ਇਸਦੇ ਪੂਰਵਜ ਦਾ ਵਿਸ਼ਲੇਸ਼ਣ ਕਰਨਾ ਪਵੇਗਾ: RFC 4226 HOTP (HMAC-Based One-Time Password)।
HOTP ਵਿੱਚ, ਕਲਾਇੰਟ ਅਤੇ ਸਰਵਰ ਇੱਕ ਇਵੈਂਟ ਕਾਊਂਟਰ $C$ ਸਾਂਝਾ ਕਰਦੇ ਹਨ। ਹਰ ਵਾਰ ਜਦੋਂ ਉਪਭੋਗਤਾ ਇੱਕ ਟੋਕਨ ਤਿਆਰ ਕਰਦਾ ਹੈ, ਕਾਊਂਟਰ ਵਧਦਾ ਹੈ ($C = C + 1$), ਅਤੇ ਟੋਕਨ $\text{HMAC-SHA-1}(K, C)$ ਤੋਂ ਲਿਆ ਜਾਂਦਾ ਹੈ। ਹਾਲਾਂਕਿ ਗਣਿਤਿਕ ਤੌਰ 'ਤੇ ਸਟੀਕ ਸੀ, ਪਰ HOTP ਇੱਕ ਕਾਰਜਸ਼ੀਲ ਕਮਜ਼ੋਰੀ ਤੋਂ ਪੀੜਤ ਸੀ: ਕਾਊਂਟਰ ਡੀਸਿੰਕ੍ਰੋਨਾਈਜ਼ੇਸ਼ਨ। ਜੇਕਰ ਕਿਸੇ ਉਪਭੋਗਤਾ ਨੇ ਅਣਜਾਣੇ ਵਿੱਚ ਆਪਣੀ ਜੇਬ ਵਿੱਚ ਹਾਰਡਵੇਅਰ ਡੋਂਗਲ ਦਾ ਬਟਨ ਪੰਜ ਵਾਰ ਦਬਾ ਦਿੱਤਾ, ਤਾਂ ਕਲਾਇੰਟ ਕਾਊਂਟਰ $C=6$ ਤੱਕ ਪਹੁੰਚ ਜਾਂਦਾ ਸੀ ਜਦੋਂ ਕਿ ਪ੍ਰਮਾਣਿਕਤਾ ਸਰਵਰ $C=1$ 'ਤੇ ਹੀ ਰਹਿੰਦਾ ਸੀ, ਜਿਸ ਨਾਲ ਲਗਾਤਾਰ ਲੌਗਇਨ ਅਸਫਲ ਹੁੰਦਾ ਸੀ।
ਮਈ 2011 ਵਿੱਚ N. M'Raihi, S. Machani, M. Pei, ਅਤੇ J. Rydell ਦੁਆਰਾ ਪ੍ਰਕਾਸ਼ਿਤ, RFC 6238 ਨੇ ਵਧ ਰਹੇ ਪੂਰਨ ਅੰਕ ਨੂੰ ਮਿਆਰੀ Unix ਯੁੱਗ ਸਮੇਂ (Epoch Time) ਨਾਲ ਬਦਲ ਕੇ ਕਾਊਂਟਰ ਡੀਸਿੰਕ ਸਮੱਸਿਆ ਦਾ ਹੱਲ ਕੀਤਾ। ਕਿਉਂਕਿ ਭੌਤਿਕ ਸਮਾਂ ਪੂਰੀ ਦੁਨੀਆ ਵਿੱਚ ਇਕਸਾਰ ਅੱਗੇ ਵਧਦਾ ਹੈ, ਕਲਾਇੰਟ ਅਤੇ ਸਰਵਰ ਦੋਵੇਂ ਬਿਨਾਂ ਕੋਈ ਨੈੱਟਵਰਕ ਪੈਕੇਟ ਭੇਜੇ ਆਪਣੇ ਅੰਦਰੂਨੀ ਕਾਊਂਟਰਾਂ ਨੂੰ ਇੱਕੋ ਸਮੇਂ ਅੱਗੇ ਵਧਾਉਂਦੇ ਹਨ।
02. TOTP ਦੇ 5 ਕ੍ਰਿਪਟੋਗ੍ਰਾਫਿਕ ਗਣਿਤਕ ਕਦਮ
ਇੱਕ 16-ਅੱਖਰਾਂ ਦੇ Base32 ਸੀਡ (ਉਦਾਹਰਨ ਲਈ, JBSWY3DPEHPK3PXP) ਨੂੰ ਇੱਕ 6-ਅੰਕੀ ਰੋਲਿੰਗ ਕੋਡ (ਉਦਾਹਰਨ ਲਈ, 284915) ਵਿੱਚ ਬਦਲਣ ਵਿੱਚ ਪੰਜ ਸਟੀਕ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫਿਕ ਪੜਾਅ ਸ਼ਾਮਲ ਹੁੰਦੇ ਹਨ:
ਐਕਸਚੇਂਜ ਨਾਮਾਂਕਣ ਕੁੰਜੀਆਂ ਨੂੰ ਵਰਣਮਾਲਾ A-Z ਅਤੇ 2-7 ਦੀ ਵਰਤੋਂ ਕਰਕੇ RFC 4648 Base32 ਵਿੱਚ ਏਨਕੋਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ (ਅਸਪਸ਼ਟ ਅੱਖਰਾਂ ਜਿਵੇਂ ਕਿ 0, 1, 8, 9 ਨੂੰ ਛੱਡ ਕੇ)। ਐਲਗੋਰਿਦਮ ਪਹਿਲਾਂ ਇਸ ਸਟ੍ਰਿੰਗ ਨੂੰ ਸਧਾਰਨ ਬਣਾਉਂਦਾ ਹੈ, ਖਾਲੀ ਥਾਵਾਂ ਹਟਾਉਂਦਾ ਹੈ ਅਤੇ ਪੈਡਿੰਗ (=) ਲਾਗੂ ਕਰਦਾ ਹੈ ਤਾਂ ਜੋ ਇਸਦੀ ਲੰਬਾਈ 8 ਦਾ ਗੁਣਜ ਹੋਵੇ, ਇਸਨੂੰ ਕੱਚੇ ਬਾਈਨਰੀ ਕੁੰਜੀ ਬਾਈਟਸ $K$ ਵਿੱਚ ਡੀਕੋਡ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ।
ਮੌਜੂਦਾ Unix ਟਾਈਮਸਟੈਂਪ (1 ਜਨਵਰੀ 1970 UTC ਤੋਂ ਬੀਤ ਚੁੱਕੇ ਸਕਿੰਟ) ਨੂੰ ਪੂਰਨ ਅੰਕ ਕਾਊਂਟਰ $T$ 'ਤੇ ਮੈਪ ਕੀਤਾ ਜਾਂਦਾ ਹੈ:
ਮਿਆਰੀ ਪੈਰਾਮੀਟਰਾਂ $T_0 = 0$ ਅਤੇ ਕਦਮ ਮਿਆਦ $X = 30$ ਸਕਿੰਟਾਂ ਦੇ ਨਾਲ। ਇਹ ਪੂਰਨ ਅੰਕ $T$ ਫਿਰ ਇੱਕ 8-ਬਾਈਟ ਬਿਗ-ਐਂਡੀਅਨ 64-ਬਿੱਟ ਅਨਸਾਈਨਡ ਪੂਰਨ ਅੰਕ ਵਜੋਂ ਏਨਕੋਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।
ਕੱਚੇ ਕੁੰਜੀ ਬਾਈਟਸ $K$ ਨੂੰ ਗੁਪਤ ਕੁੰਜੀ ਵਜੋਂ ਵਰਤਦੇ ਹੋਏ, ਅਸੀਂ 8-ਬਾਈਟ ਬਿਗ-ਐਂਡੀਅਨ ਟਾਈਮ ਬਫਰ 'ਤੇ HMAC-SHA1 ਡਾਇਜੈਸਟ ਦੀ ਗਣਨਾ ਕਰਦੇ ਹਾਂ, ਜਿਸ ਨਾਲ 20-ਬਾਈਟ (160-ਬਿੱਟ) ਸੁਨੇਹਾ ਪ੍ਰਮਾਣਿਕਤਾ ਹੈਸ਼ $HS$ ਪ੍ਰਾਪਤ ਹੁੰਦਾ ਹੈ:
20 ਕੱਚੇ ਬਾਈਟਾਂ ਨੂੰ ਇੱਕ ਪੂਰਨ ਅੰਕ ਵਿੱਚ ਬਦਲਣ ਲਈ, RFC 4226 ਡਾਇਨਾਮਿਕ ਟਰੰਕੇਸ਼ਨ ਨਿਰਧਾਰਤ ਕਰਦਾ ਹੈ:
- ਔਫਸੈੱਟ ਐਕਸਟਰੈਕਟ ਕਰੋ: ਆਖਰੀ ਬਾਈਟ $HS[19]$ ਦੀ ਜਾਂਚ ਕਰੋ ਅਤੇ ਇਸਦੇ ਹੇਠਲੇ 4 ਬਿੱਟਾਂ ਨੂੰ ਐਕਸਟਰੈਕਟ ਕਰਨ ਲਈ
0x0Fਨਾਲ ਮਾਸਕ ਕਰੋ, ਜਿਸ ਨਾਲ 0 ਅਤੇ 15 ਦੇ ਵਿਚਕਾਰ ਇੱਕ ਔਫਸੈੱਟ ਮੁੱਲ ਮਿਲਦਾ ਹੈ:Offset = HS[19] & 0x0F; - 4 ਬਾਈਟ ਸਲਾਈਸ ਕਰੋ: Offset ਤੋਂ ਸ਼ੁਰੂ ਕਰਦੇ ਹੋਏ 4 ਲਗਾਤਾਰ ਬਾਈਟਸ ਕੱਢੋ: $P = HS[Offset \dots Offset+3]$;
- ਸਾਈਨ ਬਿੱਟ ਮਾਸਕ ਕਰੋ: ਸਾਈਨਡ ਪੂਰਨ ਅੰਕ ਓਵਰਫਲੋਅ ਅਸਪਸ਼ਟਤਾ ਨੂੰ ਰੋਕਣ ਲਈ ਸਭ ਤੋਂ ਮਹੱਤਵਪੂਰਨ ਬਿੱਟ (MSB) ਨੂੰ
0x7Fਨਾਲ ਮਾਸਕ ਕਰੋ:
BinaryCode = ((P[0] & 0x7F) << 24) | ((P[1] & 0xFF) << 16) | ((P[2] & 0xFF) << 8) | (P[3] & 0xFF)
ਅੰਤ ਵਿੱਚ, ਮਿਆਰੀ 6-ਅੰਕੀ ਟੋਕਨਾਂ ਲਈ BinaryCode ਨੂੰ ਮਾਡਿਊਲੋ $10^6$ (1,000,000) ਤੱਕ ਘਟਾਓ। ਇੱਕ ਨਿਰੰਤਰ 6-ਅੱਖਰਾਂ ਵਾਲੀ ਆਊਟਪੁੱਟ ਸਟ੍ਰਿੰਗ ਨੂੰ ਯਕੀਨੀ ਬਣਾਉਣ ਲਈ ਨਤੀਜੇ ਨੂੰ ਖੱਬੇ ਪਾਸੇ ਜ਼ੀਰੋ ਨਾਲ ਪੈਡ ਕਰੋ:
03. ਚੱਲਣਯੋਗ ਕੋਡ 1: Python 3 ਸਟੈਂਡਰਡ ਲਾਇਬ੍ਰੇਰੀ
ਇਹ ਸੰਪੂਰਨ ਲਾਗੂਕਰਨ Python ਦੇ ਬਿਲਟ-ਇਨ base64, struct, hmac, ਅਤੇ hashlib ਮੋਡਿਊਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ ਜਿਸ ਵਿੱਚ ਕਿਸੇ ਬਾਹਰੀ pip ਪੈਕੇਜ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ:
import base64 import hashlib import hmac import struct import timedef generate_totp(secret_base32: str, timestamp: int = None, step: int = 30, digits: int = 6) -> str: """ Generate an RFC 6238 compliant TOTP token. :param secret_base32: Shared secret key in Base32 format (e.g., ‘JBSWY3DPEHPK3PXP’) :param timestamp: Unix epoch timestamp in seconds. Defaults to time.time() :param step: Time-step window in seconds (default: 30) :param digits: Number of output digits (default: 6) :return: Left-padded OTP string (e.g., ‘045812’) """ if timestamp is None: timestamp = int(time.time())
# 1. Normalize Base32 string and append '=' padding characters normalized_secret = secret_base32.replace(" ", "").upper() padding_needed = (8 - len(normalized_secret) % 8) % 8 normalized_secret += "=" * padding_needed key_bytes = base64.b32decode(normalized_secret) # 2. Compute 64-bit big-endian time-step counter T time_counter = timestamp // step time_bytes = struct.pack(">Q", time_counter) # 8 bytes big-endian unsigned long long # 3. Calculate HMAC-SHA1 digest (20 bytes) hmac_digest = hmac.new(key_bytes, time_bytes, hashlib.sha1).digest() # 4. Perform Dynamic Truncation offset = hmac_digest[-1] & 0x0F # Lower 4 bits of the 20th byte # Unpack 4 bytes at offset and clear MSB sign bit binary_code = struct.unpack(">I", hmac_digest[offset : offset + 4])[0] & 0x7FFFFFFF # 5. Modulo arithmetic and zero-fill formatting otp_code = binary_code % (10 ** digits) return str(otp_code).zfill(digits)
if name == “main”: test_secret = “JBSWY3DPEHPK3PXP” print(f”Generated TOTP Code: {generate_totp(test_secret)}”)
04. ਚੱਲਣਯੋਗ ਕੋਡ 2: JavaScript ਅਤੇ Node.js Crypto
ਨੇਟਿਵ crypto.createHmac ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋਏ ਬੈਕਐਂਡ Node.js ਰਨਟਾਈਮਜ਼ ਲਈ ਸ਼ੁੱਧ JavaScript ਲਾਗੂਕਰਨ:
const crypto = require('crypto');// RFC 4648 Base32 Decoder in Pure JavaScript function base32Decode(base32Str) { const alphabet = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ234567’; const cleaned = base32Str.replace(/=+$/, ”).toUpperCase().replace(/\s+/g, ”); let bits = 0, value = 0, index = 0; const output = new Uint8Array(Math.floor((cleaned.length * 5) / 8));
for (let i = 0; i < cleaned.length; i++) { const val = alphabet.indexOf(cleaned[i]); if (val === -1) continue; value = (value << 5) | val; bits += 5; if (bits >= 8) { output[index++] = (value >>> (bits - 8)) & 255; bits -= 8; } } return Buffer.from(output.buffer, 0, index); }
function generateTOTP(secretBase32, timestamp = Math.floor(Date.now() / 1000), step = 30, digits = 6) { const key = base32Decode(secretBase32); const counter = Math.floor(timestamp / step);
// Allocate 8-byte buffer in Big-Endian format const buffer = Buffer.alloc(8); buffer.writeBigUInt64BE(BigInt(counter), 0);
// Compute HMAC-SHA1 const hmac = crypto.createHmac(‘sha1’, key).update(buffer).digest();
// Dynamic Truncation const offset = hmac[hmac.length - 1] & 0x0f; const binary = ((hmac[offset] & 0x7f) << 24) | ((hmac[offset + 1] & 0xff) << 16) | ((hmac[offset + 2] & 0xff) << 8) | (hmac[offset + 3] & 0xff);
const otp = binary % (10 ** digits); return otp.toString().padStart(digits, ‘0’); }
console.log(“Calculated TOTP:”, generateTOTP(“JBSWY3DPEHPK3PXP”));
W3C Web Crypto API ਰਾਹੀਂ ਕਲਾਇੰਟ-ਸਾਈਡ ਬ੍ਰਾਊਜ਼ਰ ਐਗਜ਼ੀਕਿਊਸ਼ਨ:
100% ਔਫਲਾਈਨ ਸੁਰੱਖਿਆ ਚਾਹੁਣ ਵਾਲੀਆਂ ਆਧੁਨਿਕ ਵੈੱਬ ਐਪਲੀਕੇਸ਼ਨਾਂ ਲਈ (ਉਹੀ ਸਹੀ ਆਰਕੀਟੈਕਚਰ ਜੋ 2FA-Tool ਨੂੰ ਸ਼ਕਤੀ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ), W3C Web Crypto API ਬਿਨਾਂ ਕਿਸੇ ਥਰਡ-ਪਾਰਟੀ npm ਬੰਡਲਾਂ ਦੇ ਸਿੱਧੇ ਬ੍ਰਾਊਜ਼ਰ ਸੈਂਡਬੌਕਸ ਵਿੱਚ ਅਸਿੰਕ੍ਰੋਨਸ, ਹਾਰਡਵੇਅਰ-ਐਕਸਲਰੇਟਿਡ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫਿਕ ਪ੍ਰਿਮਿਟਿਵ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ:
async function generateBrowserTOTP(secretBase32, timestamp = Math.floor(Date.now() / 1000)) { const keyBytes = base32Decode(secretBase32); const counter = Math.floor(timestamp / 30);// 1. Import raw secret key into SubtleCrypto const cryptoKey = await window.crypto.subtle.importKey( “raw”, keyBytes, { name: “HMAC”, hash: { name: “SHA-1” } }, false, [“sign”] );
// 2. Encode 8-byte Big-Endian counter buffer const buffer = new ArrayBuffer(8); const view = new DataView(buffer); view.setBigUint64(0, BigInt(counter), false); // false = Big-Endian
// 3. Perform cryptographic HMAC sign const signature = await window.crypto.subtle.sign(“HMAC”, cryptoKey, buffer); const hmacResult = new Uint8Array(signature);
// 4. Dynamic Truncation const offset = hmacResult[hmacResult.length - 1] & 0x0f; const binary = ((hmacResult[offset] & 0x7f) << 24) | ((hmacResult[offset + 1] & 0xff) << 16) | ((hmacResult[offset + 2] & 0xff) << 8) | (hmacResult[offset + 3] & 0xff);
const otp = binary % 1000000; return otp.toString().padStart(6, ‘0’); }
05. ਚੱਲਣਯੋਗ ਕੋਡ 3: ਪ੍ਰੋਡਕਸ਼ਨ Golang (Go)
ਉੱਚ-ਥ੍ਰੂਪੁੱਟ ਮਾਈਕ੍ਰੋਸਰਵਿਸਿਜ਼ Go ਦੀ ਟੈਸਟ ਕੀਤੀ ਸਟੈਂਡਰਡ ਲਾਇਬ੍ਰੇਰੀ ਤੋਂ ਲਾਭ ਉਠਾਉਂਦੀਆਂ ਹਨ:
package mainimport ( “crypto/hmac” “crypto/sha1” “encoding/base32” “encoding/binary” “fmt” “math” “strings” “time” )
// GenerateTOTP computes standard RFC 6238 time-based tokens func GenerateTOTP(secretBase32 string, timestamp int64, step int64, digits int) (string, error) { // 1. Sanitize Base32 seed and decode cleaned := strings.ToUpper(strings.ReplaceAll(secretBase32, ” ”, "")) key, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(cleaned) if err != nil { key, err = base32.StdEncoding.DecodeString(cleaned) if err != nil { return "", err } }
// 2. Encode 64-bit Big-Endian time-step counter counter := uint64(timestamp / step) buf := make([]byte, 8) binary.BigEndian.PutUint64(buf, counter) // 3. Compute HMAC-SHA1 mac := hmac.New(sha1.New, key) mac.Write(buf) hash := mac.Sum(nil) // 4. Dynamic Truncation offset := hash[len(hash)-1] & 0x0f binaryCode := binary.BigEndian.Uint32(hash[offset:offset+4]) & 0x7fffffff // 5. Modulo arithmetic mod := uint32(math.Pow10(digits)) otp := binaryCode % mod format := fmt.Sprintf("%%0%dd", digits) return fmt.Sprintf(format, otp), nil}
func main() { code, err := GenerateTOTP(“JBSWY3DPEHPK3PXP”, time.Now().Unix(), 30, 6) if err != nil { panic(err) } fmt.Printf(“Golang Computed TOTP: %s\n”, code) }
06. RFC 6238 ਅੰਤਿਕਾ B ਟੈਸਟ ਵੈਕਟਰਾਂ ਦੀ ਪੁਸ਼ਟੀ
ਮਿਆਰੀ ਪਾਲਣਾ ਨੂੰ ਸਾਬਤ ਕਰਨ ਲਈ, ਹਰੇਕ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫਿਕ ਲਾਗੂਕਰਨ ਦੀ IETF RFC 6238 ਅੰਤਿਕਾ B ਵਿੱਚ ਪ੍ਰਕਾਸ਼ਿਤ ਅਧਿਕਾਰਤ ਟੈਸਟ ਵੈਕਟਰਾਂ ਦੇ ਵਿਰੁੱਧ ਪੁਸ਼ਟੀ ਕੀਤੀ ਜਾਣੀ ਚਾਹੀਦੀ ਹੈ।
ਅਧਿਕਾਰਤ ਟੈਸਟ ਸੂਟ ASCII ਗੁਪਤ ਕੁੰਜੀ "12345678901234567890" (20 ਬਾਈਟਸ) ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ, ਜੋ Base32 ਵਿੱਚ ਇਸ ਤਰ੍ਹਾਂ ਏਨਕੋਡ ਹੁੰਦੀ ਹੈ:
GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ (30-ਸਕਿੰਟ ਦੇ ਕਦਮਾਂ ਨਾਲ 8-ਅੰਕੀ ਆਊਟਪੁੱਟ ਲਈ ਮੁਲਾਂਕਣ ਕੀਤਾ ਗਿਆ):
| Unix Epoch ਟਾਈਮਸਟੈਂਪ | UTC ਮਿਤੀ ਅਤੇ ਸਮਾਂ | RFC ਅਧਿਕਾਰਤ ਉਮੀਦ ਕੀਤਾ ਕੋਡ | ਲਾਗੂਕਰਨ ਨਤੀਜਾ |
|---|---|---|---|
| 59 | 1970-01-01 00:00:59 | 94287082 | ✓ ਪਾਸ ਹੋਇਆ (ਸਹੀ ਮੇਲ) |
| 1111111109 | 2005-03-18 01:58:29 | 07081804 | ✓ ਪਾਸ ਹੋਇਆ (ਸਹੀ ਮੇਲ) |
| 1111111111 | 2005-03-18 01:58:31 | 14050471 | ✓ ਪਾਸ ਹੋਇਆ (ਸਹੀ ਮੇਲ) |
| 1234567890 | 2009-02-13 23:31:30 | 89005924 | ✓ ਪਾਸ ਹੋਇਆ (ਸਹੀ ਮੇਲ) |
| 2000000000 | 2033-05-18 03:33:20 | 69279037 | ✓ ਪਾਸ ਹੋਇਆ (ਸਹੀ ਮੇਲ) |
07. ਪ੍ਰੋਡਕਸ਼ਨ ਇੰਜੀਨੀਅਰਿੰਗ: ਸਕਿਊ, ਰੀਪਲੇਅ ਅਤੇ ਦਰ ਸੀਮਾਵਾਂ
ਉੱਚ-ਉਪਲਬਧਤਾ ਐਂਟਰਪ੍ਰਾਈਜ਼ ਪ੍ਰਮਾਣਿਕਤਾ ਪ੍ਰਣਾਲੀਆਂ ਵਿੱਚ TOTP ਤਸਦੀਕ ਨੂੰ ਲਾਗੂ ਕਰਦੇ ਸਮੇਂ, ਤਿੰਨ ਸੁਰੱਖਿਆ ਲੋੜਾਂ ਨੂੰ ਲਾਜ਼ਮੀ ਤੌਰ 'ਤੇ ਲਾਗੂ ਕੀਤਾ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ:
ਮੋਬਾਈਲ ਘੜੀ ਦੀਆਂ ਮਾਮੂਲੀ ਅਸ਼ੁੱਧੀਆਂ ਦੇ ਕਾਰਨ, ਸਰਵਰਾਂ ਨੂੰ [T - 1, T, T + 1] ਵਿੰਡੋ ਦਾ ਮੁਲਾਂਕਣ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ (ਪਿਛਲੇ 30 ਸਕਿੰਟ, ਮੌਜੂਦਾ 30 ਸਕਿੰਟ, ਅਤੇ ਅਗਲੇ 30 ਸਕਿੰਟਾਂ ਦੀ ਜਾਂਚ)। ਕਦੇ ਵੀ ਵਿੰਡੋ ਨੂੰ $\pm 1$ ਕਦਮ ਤੋਂ ਅੱਗੇ ਨਾ ਵਧਾਓ, ਕਿਉਂਕਿ ਹਰੇਕ ਵਾਧੂ ਕਦਮ ਰੀਪਲੇਅ ਹਮਲੇ ਦੀ ਸਤ੍ਹਾ ਨੂੰ 30 ਸਕਿੰਟਾਂ ਤੱਕ ਵਧਾ ਦਿੰਦਾ ਹੈ।
ਇੱਕ ਟੋਕਨ ਨੂੰ ਸਫਲ ਵਰਤੋਂ ਤੋਂ ਤੁਰੰਤ ਬਾਅਦ ਅਵੈਧ ਕਰ ਦਿੱਤਾ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ। Redis ਜਾਂ ਇਨ-ਮੈਮੋਰੀ ਕੈਸ਼ ਵਿੱਚ Last_Verified_Time_Step ਨੂੰ ਸਟੋਰ ਕਰੋ। ਜੇਕਰ ਕੋਈ ਕਲਾਇੰਟ ਉਸੇ 30-ਸਕਿੰਟ ਦੀ ਵਿੰਡੋ ਦੇ ਅੰਦਰ ਉਹੀ ਟੋਕਨ ਦੁਬਾਰਾ ਜਮ੍ਹਾਂ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ, ਤਾਂ ਮੈਨ-ਇਨ-ਦ-ਮਿਡਲ ਰੀਪਲੇਅ ਹਮਲਿਆਂ ਨੂੰ ਬੇਅਸਰ ਕਰਨ ਲਈ ਬੇਨਤੀ ਨੂੰ ਰੱਦ ਕਰੋ।
ਕਿਉਂਕਿ 6-ਅੰਕਾਂ ਵਾਲੇ ਕੋਡਾਂ ਵਿੱਚ ਸਿਰਫ਼ 1,000,000 ਸੰਜੋਗ ਹੁੰਦੇ ਹਨ, ਬਿਨਾਂ ਦਰ ਸੀਮਾ ਵਾਲੇ ਐਂਡਪੁਆਇੰਟਾਂ 'ਤੇ ਬਰੂਟ-ਫੋਰਸ ਹਮਲਾ ਆਸਾਨੀ ਨਾਲ ਹੋ ਸਕਦਾ ਹੈ। ਲਗਾਤਾਰ 3 ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ ਪ੍ਰਗਤੀਸ਼ੀਲ ਦੇਰੀ ਅਤੇ ਖਾਤਾ ਲਾਕਆਊਟ ਲਾਗੂ ਕਰੋ। ਕੋਡ ਵਿੱਚ, ਸਾਈਡ-ਚੈਨਲ ਟਾਈਮਿੰਗ ਵਿਸ਼ਲੇਸ਼ਣ ਨੂੰ ਨਾਕਾਮ ਕਰਨ ਲਈ ਕੰਸਟੈਂਟ-ਟਾਈਮ ਸਮਾਨਤਾ ਫੰਕਸ਼ਨਾਂ (ਉਦਾਹਰਨ ਲਈ, Go ਵਿੱਚ crypto/subtle.ConstantTimeCompare ਜਾਂ Node.js ਵਿੱਚ crypto.timingSafeEqual) ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਤੁਲਨਾ ਕਰੋ।
08. ਅਕਸਰ ਪੁੱਛੇ ਜਾਂਦੇ ਸਵਾਲ (FAQ)
ਪ੍ਰ1: ਕਿਉਂਕਿ SHA-1 ਕ੍ਰਿਪਟੋਗ੍ਰਾਫਿਕ ਤੌਰ 'ਤੇ ਕਮਜ਼ੋਰ ਹੈ, ਫਿਰ ਵੀ TOTP ਮੂਲ ਰੂਪ ਵਿੱਚ HMAC-SHA1 ਦੀ ਵਰਤੋਂ ਕਿਉਂ ਕਰਦਾ ਹੈ? ▼
ਕੱਚੇ SHA-1 ਦੇ ਵਿਰੁੱਧ ਸਿਧਾਂਤਕ ਟਕਰਾਅ (collision) ਹਮਲੇ HMAC ਨਿਰਮਾਣ (RFC 2104) ਨੂੰ ਤੋੜਦੇ ਨਹੀਂ ਹਨ। HMAC ਵਿੱਚ, ਅੰਦਰੂਨੀ ਹੈਸ਼ ਫੰਕਸ਼ਨ ਅੰਦਰੂਨੀ ਅਤੇ ਬਾਹਰੀ ਗੁਪਤ ਕੁੰਜੀਆਂ ਦੇ ਵਿਚਕਾਰ ਨੇਸਟ ਹੁੰਦਾ ਹੈ, ਜੋ ਟਕਰਾਅ-ਅਧਾਰਿਤ ਹਮਲਿਆਂ ਨੂੰ ਬੇਅਸਰ ਕਰਦਾ ਹੈ। ਅੱਜ ਤੱਕ, HMAC-SHA1 2FA ਲਈ ਪੂਰੀ ਤਰ੍ਹਾਂ ਸੁਰੱਖਿਅਤ ਹੈ। ਇਸ ਤੋਂ ਇਲਾਵਾ, ਜੇਕਰ ਉੱਚ ਸੁਰੱਖਿਆ ਭਰੋਸੇ ਦੀ ਲੋੜ ਹੋਵੇ ਤਾਂ RFC 6238 ਪੂਰੀ ਤਰ੍ਹਾਂ HMAC-SHA256 ਅਤੇ HMAC-SHA512 ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ।
ਪ੍ਰ2: ਕੀ ਸਮਾਂ ਖੇਤਰ (Time Zones) ਜਾਂ ਡੇਲਾਈਟ ਸੇਵਿੰਗ ਟਾਈਮ (DST) TOTP ਸਿੰਕ੍ਰੋਨਾਈਜ਼ੇਸ਼ਨ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕਰਦੇ ਹਨ? ▼
ਨਹੀਂ। Unix ਯੁੱਗ ਸਮਾਂ 1970-01-01 00:00:00 UTC ਤੋਂ ਬੀਤ ਚੁੱਕੇ ਸਕਿੰਟਾਂ ਵਜੋਂ ਪਰਿਭਾਸ਼ਿਤ ਕੀਤਾ ਗਿਆ ਹੈ। ਇਹ ਸਮਾਂ ਖੇਤਰਾਂ, ਲੀਪ ਸਕਿੰਟਾਂ, ਅਤੇ ਡੇਲਾਈਟ ਸੇਵਿੰਗ ਸ਼ਿਫਟਾਂ ਤੋਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਸੁਤੰਤਰ ਹੈ। ਸਮੇਂ ਦੇ ਕਿਸੇ ਵੀ ਸਹੀ ਪਲ 'ਤੇ, ਟੋਕੀਓ ਵਿੱਚ ਇੱਕ ਸਰਵਰ ਅਤੇ ਕੈਲੀਫੋਰਨੀਆ ਵਿੱਚ ਇੱਕ ਸਮਾਰਟਫੋਨ ਦਾ ਬਿਲਕੁਲ ਉਹੀ ਪੂਰਨ ਅੰਕ ਟਾਈਮਸਟੈਂਪ ਹੁੰਦਾ ਹੈ।
ਪ੍ਰ3: Steam Guard ਦਾ 5-ਅੱਖਰੀ ਪ੍ਰਮਾਣੀਕਰਨ RFC 6238 ਤੋਂ ਕਿਵੇਂ ਵੱਖਰਾ ਹੈ? ▼
Steam Guard RFC 6238 'ਤੇ ਆਧਾਰਿਤ ਇੱਕ ਮਲਕੀਅਤ ਵਾਲਾ ਰੂਪ ਹੈ। ਇਹ ਬਿਲਕੁਲ ਉਹੀ 30-ਸਕਿੰਟ ਸਮਾਂ-ਕਦਮ ਅਤੇ HMAC-SHA1 ਗਣਨਾ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ, ਪਰ ਅੰਤਮ ਕਟੌਤੀ ਪੜਾਅ ਵਿੱਚ, ਇਹ 5-ਅੱਖਰਾਂ ਵਾਲੀ ਸਟ੍ਰਿੰਗ ਬਣਾਉਣ ਲਈ ਇੱਕ ਕਸਟਮ 26-ਅੱਖਰਾਂ ਵਾਲੀ ਅਲਫਾਨਿਊਮੇਰਿਕ ਅਰੇ (23456789BCDFGHJKMNPQRTVWXY) ਰਾਹੀਂ ਐਕਸਟਰੈਕਟ ਕੀਤੇ ਪੂਰਨ ਅੰਕ ਨੂੰ ਮੈਪ ਕਰਦਾ ਹੈ।
100% ਕਲਾਇੰਟ-ਸਾਈਡ TOTP ਕੋਡ ਜਨਰੇਸ਼ਨ ਦਾ ਲਾਈਵ ਅਨੁਭਵ ਕਰੋ
2FA-Tool W3C Web Crypto API ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਸਿੱਧੇ ਤੁਹਾਡੇ ਬ੍ਰਾਊਜ਼ਰ ਦੇ ਅੰਦਰ ਇਸ ਸਹੀ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫਿਕ ਪਾਈਪਲਾਈਨ ਨੂੰ ਲਾਗੂ ਕਰਦਾ ਹੈ। ਜ਼ੀਰੋ ਸਰਵਰ ਟ੍ਰਾਂਸਮਿਸ਼ਨ, ਜ਼ੀਰੋ ਟੋਕਨ ਸਟੋਰੇਜ, ਤੁਰੰਤ ਪ੍ਰਮਾਣਿਕਤਾ।