💻 عملی کرپٹوگرافی · انجینئرنگ کا تفصیلی جائزہ

TOTP کیسے کام کرتا ہے: Python، JavaScript اور Go میں RFC 6238 الگورتھم کا نفاذ

2F 2FA-Tool سیکیورٹی ریسرچ لیب · اپ ڈیٹ: اکتوبر 2026 · 16 منٹ کا مطالعہ (2,700+ الفاظ) ✓ 2026 کے لیے تصدیق شدہ
💡 آرکیٹیکچرل خلاصہ اور انجینئرنگ کا منشور

جدید ویب سیکیورٹی کے بنیادی کرپٹوگرافک پروٹوکولز میں، RFC 6238 (TOTP: Time-Based One-Time Password Algorithm) اپنی ریاضیاتی سادگی کی بدولت نمایاں مقام رکھتا ہے۔ اسے کسی انٹرایکٹو نیٹ ورک ہینڈ شیک، سینٹرلائزڈ پبلک کی انفراسٹرکچر (PKI)، یا کلاؤڈ راؤنڈ ٹرپس کی ضرورت نہیں ہوتی۔ صرف ایک مشترکہ Base32 خفیہ کلید (Secret Key) اور فزیکل یونکس وقت کے مستقل آگے بڑھنے کے ذریعے، کلائنٹ اور سرور ہر 30 سیکنڈ بعد 100% ریاضیاتی یقین کے ساتھ یکساں، عارضی 6 ہندسی توثیقی ٹوکنز تیار کرتے ہیں۔

اس جامع رہنما میں، ہم بلیک باکس تھرڈ پارٹی لائبریریوں (جیسے pyotp یا otplib) سے گریز کرتے ہوئے Python، JavaScript اور Go میں مکمل RFC 6238 کرپٹوگرافک پائپ لائن کو بالکل ابتدا سے تیار کریں گے، اور باضابطہ IETF ٹیسٹ ویکٹرز سے ہر نفاذ کی توثیق کریں گے۔

01. وقت کے زیر انتظام تصدیق (Authentication) کی خوبصورتی

TOTP کو سمجھنے کے لیے، ہمیں سب سے پہلے اس کے پیش رو کا جائزہ لینا چاہیے: RFC 4226 HOTP (HMAC-Based One-Time Password)۔

HOTP میں، کلائنٹ اور سرور ایک مشترکہ ایونٹ کاؤنٹر $C$ استعمال کرتے ہیں۔ جب بھی صارف ٹوکن بناتا ہے، کاؤنٹر میں ایک عدد اضافہ ہوتا ہے ($C = C + 1$)، اور ٹوکن $\text{HMAC-SHA-1}(K, C)$ سے اخذ کیا جاتا ہے۔ اگرچہ ریاضیاتی طور پر یہ درست تھا، لیکن HOTP کو ایک سنگین عملی کمزوری کا سامنا تھا: کاؤنٹر کی غیر مطابقت (Counter Desynchronization)۔ اگر صارف کی جیب میں اس کے ہارڈویئر ڈونگل کا بٹن اتفاقیہ طور پر پانچ بار دب جائے تو کلائنٹ کاؤنٹر $C=6$ پر پہنچ جاتا تھا جبکہ توثیقی سرور بدستور $C=1$ پر رہتا تھا، جس کے نتیجے میں لاگ ان مسلسل مسترد ہوتا رہتا تھا۔

⏱️ RFC 6238 کی پیش رفت: ایونٹ کاؤنٹرز کو ای پوک ٹائم (Epoch Time) سے بدلنا

مئی 2011 میں N. M'Raihi، S. Machani، M. Pei، اور J. Rydell کی جانب سے شائع ہونے والے RFC 6238 نے بڑھتے ہوئے عددی کاؤنٹر کی جگہ معیاری یونکس ای پوک ٹائم (Unix Epoch Time) متعارف کروا کر کاؤنٹر ڈی سنک کا مسئلہ حل کیا۔ چونکہ طبعی وقت دنیا بھر میں یکساں رفتار سے آگے بڑھتا ہے، اس لیے کلائنٹ اور سرور بغیر کوئی نیٹ ورک پیکٹ بھیجے بیک وقت اپنے اندرونی کاؤنٹرز کو یکساں طور پر آگے بڑھاتے ہیں۔

02. TOTP کے 5 کرپٹوگرافک حسابی مراحل

16 حروف پر مشتمل Base32 سیڈ (مثلاً JBSWY3DPEHPK3PXP) کو 6 ہندسی متحرک کوڈ (مثلاً 284915) میں تبدیل کرنا پانچ قطعی کرپٹوگرافک مراحل پر مشتمل ہے:

1 مرحلہ 1: Base32 خفیہ کلید کی ڈیکوڈنگ (Base32 Secret Key Decoding)

ایکسچینج اندراج کی کلیدیں RFC 4648 Base32 میں حروف تہجی A-Z اور 2-7 کا استعمال کرتے ہوئے اینکوڈ کی جاتی ہیں (مبہم حروف جیسے 0, 1, 8, 9 کو چھوڑ کر)۔ الگورتھم سب سے پہلے اس اسٹرنگ کو نارملائز کرتا ہے، اسپیسز کو خارج کرتا ہے اور پیڈنگ (=) نافذ کرتا ہے تاکہ اس کی لمبائی 8 کا حاصل ضرب ہو، جس کے بعد اسے خام بائنری کلیدی بائٹس $K$ میں ڈیکوڈ کیا جاتا ہے۔

2 مرحلہ 2: ٹائم اسٹیپ کا حساب (کاؤنٹر $T$)

موجودہ یونکس ٹائم اسٹیمپ (1 جنوری 1970 UTC سے اب تک گزرے ہوئے سیکنڈز) کو انٹیجر کاؤنٹر $T$ پر میپ کیا جاتا ہے:

T = floor( (CurrentTime - T0) / X )

معیاری پیرامیٹرز $T_0 = 0$ اور اسٹیپ کی مدت $X = 30$ سیکنڈز کے ساتھ۔ اس انٹیجر $T$ کو پھر 8 بائٹ بگ-اینڈین (Big-Endian) 64 بٹ غیر دستخط شدہ انٹیجر کے طور پر اینکوڈ کیا جاتا ہے۔

3 مرحلہ 3: HMAC-SHA1 ہیش کا حساب

خام کی بائٹس $K$ کو بطور خفیہ کلید استعمال کرتے ہوئے، ہم 8 بائٹ کے بگ-اینڈین ٹائم بفر پر HMAC-SHA1 ڈائجسٹ کا حساب لگاتے ہیں، جس سے 20 بائٹ (160 بٹ) میسج کی توثیق کا ہیش $HS$ حاصل ہوتا ہے:

HS = HMAC-SHA-1(Key, T)
4 مرحلہ 4: ڈائنامک ٹرنکیشن (Dynamic Truncation - DT)

20 خام بائٹس کو ایک انٹیجر میں تبدیل کرنے کے لیے، RFC 4226 ڈائنامک ٹرنکیشن کا طریقہ وضع کرتا ہے:

  • آفسیٹ اخذ کرنا: آخری بائٹ $HS[19]$ کو دیکھیں اور اس کے نچلے 4 بٹس حاصل کرنے کے لیے 0x0F سے ماسک کریں، جس سے 0 اور 15 کے درمیان آفسیٹ ویلیو حاصل ہوتی ہے: Offset = HS[19] & 0x0F؛
  • 4 بائٹس کا ٹکڑا الگ کرنا: آفسیٹ سے شروع ہونے والے مسلسل 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)
5 مرحلہ 5: $N$ ہندسوں تک ماڈیولو ریڈکشن (Modulo Reduction)

آخر میں، معیاری 6 ہندسی ٹوکنز کے لیے BinaryCode کا ماڈیولو $10^6$ (1,000,000) نکالیں۔ مستقل 6 حروف پر مشتمل آؤٹ پٹ اسٹرنگ کو یقینی بنانے کے لیے بائیں جانب زیروز کا اضافہ (Left-pad with zeroes) کریں:

OTP = BinaryCode mod 10^6

03. قابل عمل کوڈ 1: Python 3 معیاری لائبریری

یہ مکمل نفاذ بغیر کسی بیرونی pip پیکیج کے Python کے بلٹ ان ماڈیولز base64، struct، hmac اور hashlib کا استعمال کرتا ہے:

totp_rfc6238.py Python 3.8+ (Zero Dependencies)
import base64
import hashlib
import hmac
import struct
import time

def 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 نفاذ:

totp_node.js Node.js Native Crypto
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 بنڈلز کے بغیر براہ راست براؤزر سینڈ باکس میں غیر متضاد (Asynchronous) اور ہارڈویئر کی مدد سے چلنے والے کرپٹو پرائمیٹوز فراہم کرتا ہے:

webcrypto_totp.js Browser W3C Web Crypto API
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 کی مستند اور آزمودہ معیاری لائبریری سے بھرپور فائدہ اٹھاتی ہیں:

totp.go Go 1.20+ Standard Library
package main

import ( “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 (Appendix B) میں شائع کردہ باضابطہ ٹیسٹ ویکٹرز کے خلاف جانچا جانا چاہیے۔

باضابطہ ٹیسٹ سویٹ ASCII خفیہ کلید "12345678901234567890" (20 بائٹس) کا استعمال کرتا ہے، جو Base32 میں یوں اینکوڈ ہوتی ہے:
GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ (30 سیکنڈ کے مراحل کے ساتھ 8 ہندسوں کے آؤٹ پٹ کے لیے جانچا گیا):

یونکس ای پوک ٹائم اسٹیمپ 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 کی توثیق کو لاگو کرتے وقت، تین سیکیورٹی تقاضوں کا نفاذ ناگزیر ہے:

قاعدہ 1 کلاک ڈرفٹ ٹالرنس ونڈو (Clock Drift Tolerance Window)

موبائل فونز کی گھڑیوں میں معمولی بے قاعدگی کی وجہ سے، سرورز کو [T - 1, T, T + 1] کی ونڈو کا جائزہ لینا چاہیے (پچھلے 30 سیکنڈز، موجودہ 30 سیکنڈز، اور اگلے 30 سیکنڈز کی جانچ)۔ اس ونڈو کو کبھی بھی $\pm 1$ اسٹیپ سے آگے مت بڑھائیں، کیونکہ ہر اضافی مرحلہ ری پلے حملے کے دورانیے کو مزید 30 سیکنڈز تک بڑھا دیتا ہے۔

قاعدہ 2 سنگل یوز ٹوکن کا نفاذ (اینٹی ری پلے)

کامیاب استعمال کے فوراً بعد ٹوکن کو کالعدم کر دیا جانا چاہیے۔ Redis یا اِن میموری کیش میں Last_Verified_Time_Step محفوظ کریں۔ اگر کلائنٹ اسی 30 سیکنڈ کی ونڈو میں وہی ٹوکن دوبارہ جمع کرانے کی کوشش کرے، تو مین ان دی مڈل (MitM) ری پلے حملوں کو بے اثر کرنے کے لیے درخواست کو مسترد کر دیں۔

قاعدہ 3 بروٹ فورس ریٹ لمٹنگ اور کانسٹنٹ ٹائم موازنہ

چونکہ 6 ہندسی کوڈز کے صرف 1,000,000 ممکنہ امتزاج ہوتے ہیں، اس لیے بلا روک ٹوک والے اینڈ پوائنٹس پر تیزی سے بروٹ فورس حملہ کیا جا سکتا ہے۔ مسلسل 3 ناکامیوں کے بعد بتدریج تاخیر اور اکاؤنٹ لاک آؤٹ نافذ کریں۔ کوڈ میں، سائیڈ چینل ٹائمنگ کے تجزیے کو ناکام بنانے کے لیے ہمیشہ مستقل وقت (Constant-Time) والے مساوات کے فنکشنز استعمال کریں (جیسے Go میں crypto/subtle.ConstantTimeCompare یا Node.js میں crypto.timingSafeEqual)۔

08. کثرت سے پوچھے جانے والے سوالات (FAQ)

سوال 1: چونکہ SHA-1 کرپٹوگرافک طور پر غیر محفوظ ہو چکا ہے، تو TOTP اب بھی HMAC-SHA1 کو ڈیفالٹ کے طور پر کیوں استعمال کرتا ہے؟ ▼

خام SHA-1 کے خلاف نظریاتی تصادم کے حملے (Collision attacks) HMAC کی تعمیر (RFC 2104) کو غیر محفوظ نہیں بناتے۔ HMAC میں، بنیادی ہیش فنکشن اندرونی اور بیرونی خفیہ کیز کے اندر نیسٹڈ ہوتا ہے، جو تصادم پر مبنی حملوں کو بے اثر کر دیتا ہے۔ موجودہ دور میں بھی 2FA کے لیے HMAC-SHA1 محفوظ ہے۔ مزید برآں، اگر اعلیٰ سطح کی یقین دہانی درکار ہو تو RFC 6238 مکمل طور پر HMAC-SHA256 اور HMAC-SHA512 کی بھی اجازت دیتا ہے۔

سوال 2: کیا ٹائم زونز یا ڈے لائٹ سیونگ ٹائم (DST) TOTP کی ہم آہنگی کو متاثر کرتے ہیں؟ ▼

نہیں۔ یونکس ای پوک ٹائم کی تعریف 1970-01-01 00:00:00 UTC سے اب تک گزرے ہوئے سیکنڈز کے طور پر کی گئی ہے۔ یہ ٹائم زونز، لیپ سیکنڈز اور ڈے لائٹ سیونگ کی تبدیلیوں سے مکمل طور پر بے نیاز ہے۔ کسی بھی قطعی لمحے پر، ٹوکیو کے سرور اور کیلیفورنیا کے اسمارٹ فون دونوں کے پاس بالکل یکساں انٹیجر ٹائم اسٹیمپ ہوتا ہے۔

سوال 3: Steam Guard کی 5 حروف والی تصدیق RFC 6238 سے کس طرح مختلف ہے؟ ▼

Steam Guard ایک ملکیتی (Proprietary) طریقہ کار ہے جو RFC 6238 پر مبنی ہے۔ یہ بالکل وہی 30 سیکنڈ کا ٹائم اسٹیپ اور HMAC-SHA1 کا حسابی عمل استعمال کرتا ہے، لیکن آخری ریڈکشن کے مرحلے میں، یہ اخذ کردہ انٹیجر کو ایک کسٹم 26 حروف والے حروف نمبری کیریکٹر ارے (23456789BCDFGHJKMNPQRTVWXY) کے ذریعے میپ کر کے 5 حروف کی اسٹرنگ تیار کرتا ہے۔

RFC 6238 سے مطابقت پذیر · W3C Web Crypto API کلائنٹ سائڈ کمپیوٹنگ

100% کلائنٹ سائڈ TOTP کوڈ جنریشن کا لائیو تجربہ کریں

2FA-Tool W3C Web Crypto API کا استعمال کرتے ہوئے اس قطعی کرپٹوگرافک پائپ لائن کو براہ راست آپ کے براؤزر کے اندر چلاتا ہے۔ سرور پر زیرو ٹرانسمیشن، زیرو ٹوکن اسٹوریج، اور فوری توثیق۔