সরাসরি পর্বে যান
পর্ব ১৬ · ৮০-এর মধ্যে · মডিউল ৩

MFA আর passkey — TOTP, FIDO2 আর phishing-প্রতিরোধী login

MFA and Passkeys — TOTP, FIDO2 & Phishing-Resistant Login

Taught in Bangla, this lesson shows what MFA stops and what it does not, the risks of SMS and voice OTP including SIM swap and its process defences, HOTP and TOTP worked by hand, verifier rules on window, replay and secret storage, push fatigue and number matching, real-time relay and origin binding, WebAuthn ceremonies, synced and device-bound passkeys, recovery weaknesses and organisation rollout.

এই পর্বে যা শিখবেন

  • MFA ঠিক কোন বিপদ ঠেকায় আর কোনটি ঠেকায় না
  • SMS আর voice OTP-র ঝুঁকি, SIM swap আর তার প্রক্রিয়াগত প্রতিরক্ষা
  • HOTP আর TOTP হাতে হিসাব করা, window, replay আর secret রাখার নিয়ম
  • Push fatigue, number matching, relay আর origin binding-এর আসল পার্থক্য
  • WebAuthn ceremony, synced আর device-bound passkey, recovery আর প্রতিষ্ঠানে rollout

সীমারেখা: এই পর্ব রক্ষকের জন্য। এখানে হামলার ধরন শুধু ধারণা হিসেবে আছে, যাতে প্রতিরক্ষা বোঝা যায়। কোড চলে খেলনা ডেটা আর RFC-র প্রকাশ্য test secret নিয়ে। অন্যের account, SIM বা login-এ অনুমতি ছাড়া পরীক্ষা করা অপরাধ হতে পারে। পর্ব ৬-এর লিখিত অনুমতির নিয়ম এখানেও প্রযোজ্য।

১ · MFA কেন কাজ করে, আর কী থামায় না

ব্যাংকের লকারের কথা ভাবুন। একটি চাবি থাকে আপনার হাতে, আরেকটি ব্যাংকের কর্মকর্তার কাছে। দুটি একসঙ্গে না ঘুরলে লকার খোলে না। আপনার চাবি হারালেও চোরের কাজ শেষ হয় না। MFA মানে multi-factor authentication. ভাবনাটি একই: একটি প্রমাণ হারালেও দরজা বন্ধ থাকবে।

পর্ব ১৩-এ দেখেছেন, password ফাঁস হয়, আর মানুষ একই password বহু জায়গায় ব্যবহার করেন। পর্ব ১৫-এ authentication-এর ভিত্তি আছে। এই পর্ব সেখান থেকে এগোয়। প্রশ্নটি হলো, password চুরি হলেও login কীভাবে আটকানো যায়?

তিন ধরনের প্রমাণ

প্রতিটি প্রমাণের ধরনকে বলে authentication factor. প্রচলিত তিন ধরন হলো:

  • যা আপনি জানেন: password, PIN.
  • যা আপনার কাছে আছে: ফোন, security key, OTP যন্ত্র।
  • আপনি নিজে: আঙুলের ছাপ, মুখ।

দুটি password দিলে MFA হয় না, কারণ দুটিই একই ধরনের। একসঙ্গে দুটি ভিন্ন ধরনের প্রমাণ চাই। তবে শুধু ধরন গুনলে চলে না। Password আর TOTP secret একই password manager-এ রাখলে একটি জায়গা হারানোই দুটি হারানো। সুবিধা বাড়ে, পৃথকীকরণ কমে। সিদ্ধান্তটি সচেতনভাবে নিন।

ঝুঁকিশুধু passwordSMS OTPTOTPPush + number matchingPasskey / security key
Credential stuffingঠেকায় নাঠেকায়ঠেকায়ঠেকায়ঠেকায়
SIM swapপ্রযোজ্য নয়ঝুঁকিতেঠেকায়সাধারণত ঠেকায়ঠেকায়
Push-এ ক্লান্ত করাপ্রযোজ্য নয়প্রযোজ্য নয়প্রযোজ্য নয়অনেকটা কমায়প্রযোজ্য নয়
Real-time phishing relayঠেকায় নাঠেকায় নাঠেকায় নাঠেকায় নাঠেকায়
Server database ফাঁসhash-এর মান নির্ভরphone নম্বর ফাঁসseed ফাঁস হলে বিপদtoken-এর নকশা নির্ভরশুধু public key
Login-এর পরে session চুরিঠেকায় নাঠেকায় নাঠেকায় নাঠেকায় নাঠেকায় না

শেষ সারিটি মনে রাখুন। MFA শুধু login-এর মুহূর্ত রক্ষা করে। Login শেষে যে session cookie তৈরি হয়, সেটি চুরি হলে কোনো MFA আবার জিজ্ঞেস করে না। সে আলোচনা পর্ব ১৭-এ। যন্ত্রে malware থাকলে, অথবা ব্যবহারকারী ফাঁদে পড়ে কোনো অনুমতি দিলে, কিংবা application-এ authorization-এর ভুল থাকলেও MFA সাহায্য করে না। এটি একটি স্তর, পুরো দেয়াল নয়। পর্ব ৩-এর defense in depth এখানেও খাটে।

২ · SMS আর voice OTP — মোবাইল ব্যাংকিংয়ের চেনা অভ্যাসের ঝুঁকি

বাংলাদেশে অনেকের কাছে MFA মানেই ফোনে আসা ছয় অঙ্কের OTP. মোবাইল ব্যাংকিং, কার্ডের অনলাইন লেনদেন, সরকারি সেবা, সব জায়গায় এটি পরিচিত। এর বড় গুণ হলো নাগালের বিস্তার। সাধারণ বাটন ফোনেও SMS আসে, কোনো app লাগে না। তাই এটিকে তুচ্ছ করা ভুল। কিছু না থাকার চেয়ে SMS OTP অনেক ভালো। তবে এর দুর্বলতাও জানা দরকার।

SMS OTP যেন পাড়ার ডাকপিয়নের হাতে পাঠানো খোলা পোস্টকার্ড। চিঠিটি পথ চিনে যায় ঠিকানায়, মানুষের কাছে নয়। কেউ ঠিকানাটি নিজের নামে বদলে নিতে পারলে চিঠি তার কাছেই যাবে। Phone নম্বরও তেমনি একটি ঠিকানা, যন্ত্র নয়।

কোথায় দুর্বল

  • SIM swap: কেউ প্রতারণা করে বা ভেতরের সাহায্যে আপনার নম্বর নতুন SIM-এ তুলে নেয়। এরপর OTP তার ফোনে যায়, আর আপনার ফোনের সংযোগ হঠাৎ বন্ধ হয়ে যায়।
  • নম্বর পুনর্ব্যবহার: বহুদিন বন্ধ থাকা নম্বর অপারেটর আবার অন্য কাউকে দিতে পারে। পুরোনো অ্যাকাউন্টের OTP তখন নতুন মালিকের কাছে যেতে পারে।
  • পথের দুর্বলতা: টেলিফোন network-এর সংকেত ব্যবস্থা পুরোনো যুগের নকশা। SMS end-to-end encrypted নয়।
  • মানুষকে ঠকানো: “আপনার অ্যাকাউন্ট বন্ধ হবে, code-টি বলুন” ধরনের ফোন social engineering-এর চেনা রূপ। Voice OTP-তে একই ঝুঁকি, সঙ্গে ভয়েসমেইল আর কল ফরওয়ার্ডের প্রশ্নও আসে।
  • ফোনের ভেতরের ঝুঁকি: lock screen-এ দেখা যাওয়া code, অথবা SMS পড়ার অনুমতি পাওয়া ক্ষতিকর app.

একটি অভ্যাস বদলান: OTP আর PIN কাউকে বলা যাবে না। ব্যাংক, এজেন্ট বা “কাস্টমার কেয়ার” পরিচয় দিলেও নয়। ফোনে হঠাৎ network চলে গেলে আর কারণ বোঝা না গেলে দেরি না করে অপারেটর আর ব্যাংকের আসল নম্বরে যোগাযোগ করুন। সেটি SIM swap-এর লক্ষণ হতে পারে।

প্রতিরক্ষা: অপারেটর, সেবাদাতা আর ব্যবহারকারী

অপারেটরের প্রক্রিয়া

SIM বদলের আগে শক্ত পরিচয় যাচাই, কর্মীর কাজের audit log, এক কর্মী একা বড় পরিবর্তন করতে না পারা, SIM বদলের পরে গ্রাহককে জানানো।

Process control

সেবাদাতার নকশা

SIM বদল বা নম্বর port হওয়ার সংকেত দেখলে বড় লেনদেন সাময়িক আটকে যাচাই করা, নতুন যন্ত্রে অ্যাকাউন্ট বাঁধা কঠিন করা, লেনদেনের পরিমাণ আর প্রাপক SMS-এ দেখানো।

Risk signal

ব্যবহারকারী

গুরুত্বপূর্ণ অ্যাকাউন্টে app বা passkey বেছে নেওয়া, নম্বর বদলালে সব জায়গায় হালনাগাদ করা, অচেনা OTP এলে সেটিকে সতর্কসংকেত হিসেবে দেখা।

Habit

বাংলাদেশে SIM নিবন্ধনে আঙুলের ছাপের ব্যবহার একটি বড় প্রক্রিয়াগত পদক্ষেপ ছিল। ITU-সংশ্লিষ্ট আর্থিক অন্তর্ভুক্তি উদ্যোগ FIGI-র নিরাপত্তা সুপারিশেও SIM বদলের আগে biometric যাচাই আর আর্থিক সেবাদাতাকে জানানোর কথা আছে। তবে নিয়ম আর চর্চা সময়ের সঙ্গে বদলায়। আপনার সেবার জন্য বর্তমান নিয়ম নিয়ন্ত্রকের সরকারি উৎসে দেখে নিন। কোনো প্রক্রিয়াই শতভাগ নয়, কারণ ভুল আর ভেতরের সহায়তা থেকেই যায়।

NIST-এর অবস্থানও শিক্ষণীয়। SP 800-63B-4 (২০২৫) phone network দিয়ে OTP পাঠানোকে restricted বলে। অর্থাৎ চলতে পারে, তবে ঝুঁকি বিবেচনা করতে হবে, বিকল্প দিতে হবে, ব্যবহারকারীকে ঝুঁকি জানাতে হবে, আর সরে যাওয়ার পরিকল্পনা রাখতে হবে। ঝুঁকির সংকেত হিসেবে যন্ত্র বদল, SIM বদল আর নম্বর port হওয়ার কথা সেখানে আছে। NIST মূলত মার্কিন সরকারি সংস্থার নির্দেশিকা, তবে বিশ্বজুড়ে একটি ভালো মাপকাঠি।

৩ · HOTP আর TOTP — সময় থেকে ছয় অঙ্ক

SMS-এর সমস্যা হলো code পথে চলে। তাহলে এমন ব্যবস্থা ভাবুন, যেখানে code পাঠাতেই হয় না। ফোন আর server দুজনেই নিজে নিজে একই সংখ্যা হিসাব করে। দরকার শুধু একটি অভিন্ন গোপন মান, যাকে বলে shared secret. আর দরকার এমন কিছু, যা প্রতিবার বদলায়।

HOTP (RFC 4226, ২০০৫)-এ বদলানোর মান হলো একটি counter. Button চাপলে counter বাড়ে। TOTP (RFC 6238, ২০১১)-এ counter-এর জায়গায় সময়। সূত্র দুটি হলো:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C))
TOTP(K, t) = HOTP(K, ⌊t / 30⌋)

এখানে K হলো secret, আর ভেতরের যন্ত্রটি পর্ব ৯-এর HMAC. SHA-1-এর collision দুর্বলতা জানা, কিন্তু HMAC-এর নিরাপত্তা সরাসরি collision-এর ওপর নির্ভর করে না। তাই TOTP-তে SHA-1 থাকলেই code ভাঙা যায়, এমন নয়। RFC 6238 SHA-256 আর SHA-512-ও অনুমোদন করে। তবে বহু app-এ SHA-1, ছয় অঙ্ক আর ৩০ সেকেন্ডই সবচেয়ে সামঞ্জস্যপূর্ণ।

নিচের ডায়াগ্রামে RFC 6238-এর আসল test secret আর আসল সময় দিয়ে একটি code তৈরি হবে। প্রতিটি মান script চালিয়ে পাওয়া। “পরে” চেপে এগোন।

  1. SecretKদুই পক্ষে একই
  2. সময়T৩০ সেকেন্ডের ধাপ
  3. HMAC20 byteSHA-1
  4. Truncate4 byteটুকরো বাছাই
  5. Code005924ছয় অঙ্ক
KRFC-র প্রকাশ্য test secret
ASCII : 12345678901234567890  (20 byte)
Base32: GEZDGNBVGY3TQOJQ
        GEZDGNBVGY3TQOJQ
সময়Unix time (UTC)
t = 1234567890
  = 2009-02-13 23:31:30 UTC
Counter৮ byte, big-endian
T = floor(1234567890 / 30)
  = 41152263
  = 0x273EF07

bytes: 00 00 00 00 02 73 EF 07
HMAC-SHA-1(K, T)২০ byte
90 7c d1 a9 11 65 64 ec b9 d5
d1 78 03 25 f2 46 17 3f e7 03
Dynamic truncationoffset = শেষ byte-এর নিচের ৪ bit
শেষ byte = 0x03, offset = 3

90 7c d1 a9 11 65 64 ec b9 d5
index:    3  4  5  6
Maskসবচেয়ে ওপরের bit বাদ
0xa9116564 & 0x7fffffff
= 0x29116564
= 689005924
Moduloছয় অঙ্ক রাখা
689005924 mod 10^6 = 5924
ফোনে দেখায়: 005924

৮ অঙ্কে (RFC vector): 89005924
  1. Secret. Enrollment-এর সময় server একটি random secret বানিয়ে QR code-এ ফোনকে দেয়। এখানে RFC-র ২০ byte test secret, যা প্রকাশ্য, কোনো আসল account-এর নয়। QR code-টিই secret, তাই এর screenshot রাখা নিরাপদ নয়।
  2. সময়। ফোন আর server দুজনেই ঘড়ি দেখে। এখানে t = 1234567890 সেকেন্ড, যা ২০০৯ সালের ১৩ ফেব্রুয়ারি UTC সময়। Timezone কোনো ভূমিকা রাখে না, কারণ Unix time সব জায়গায় একই।
  3. Counter. সময়কে ৩০ দিয়ে ভাগ করে নিচের দিকে পূর্ণসংখ্যা নেওয়া হয়: T = 41152263. ৩০ সেকেন্ডের প্রতিটি time step-এ T একই থাকে, তাই code-ও একই থাকে। T-কে ৮ byte-এ লেখা হয়।
  4. HMAC. Secret দিয়ে T-এর HMAC-SHA-1 হলো ২০ byte. Secret ছাড়া এই মান আগে থেকে বলা যায় না, আর code দেখে secret বের করাও কার্যত অসম্ভব।
  5. Dynamic truncation. ২০ byte মানুষের লেখার মতো নয়। শেষ byte 0x03-এর নিচের ৪ bit থেকে offset 3 পাওয়া গেল। Index 3 থেকে ৪ byte নেওয়া হলো: a9 11 65 64.
  6. Mask. সবচেয়ে ওপরের bit মুছে ফেলা হয়, যাতে signed আর unsigned সংখ্যার পার্থক্যে ভাষাভেদে ফল না বদলায়। 0xa9 হলো 0x29, আর মান দাঁড়ায় 689005924.
  7. Modulo. 10^6 দিয়ে ভাগশেষ 5924. বাঁয়ে শূন্য বসিয়ে 005924. তাই code-কে সংখ্যা হিসেবে রাখলে ভুল হয়, string হিসেবে তুলনা করতে হয়। RFC-র ৮ অঙ্কের vector 89005924-এর শেষ ছয় অঙ্কও এটিই।

এবার একই হিসাব সত্যিকারের কোডে দেখুন। শুধু standard library, কোনো network নেই। কোডটি RFC 6238-এর Appendix B-র SHA-1 vector-এর সঙ্গে নিজের ফল মিলিয়ে দেখে।

import hashlib, hmac, struct

SECRET = b"12345678901234567890"   # RFC 6238 public test secret

def totp(secret, unix_time, digits=8, step=30):
    counter = unix_time // step
    msg = struct.pack(">Q", counter)            # 8 bytes, big-endian
    digest = hmac.new(secret, msg, hashlib.sha1).digest()
    offset = digest[-1] & 0x0F                  # dynamic truncation
    chunk = digest[offset:offset + 4]
    value = int.from_bytes(chunk, "big") & 0x7FFFFFFF
    return f"{value % 10**digits:0{digits}d}"

# RFC 6238 Appendix B, SHA-1 rows
VECTORS = [(59, "94287082"), (1111111109, "07081804"),
           (1111111111, "14050471"), (1234567890, "89005924"),
           (2000000000, "69279037"), (20000000000, "65353130")]

for t, expected in VECTORS:
    got = totp(SECRET, t)
    ok = hmac.compare_digest(got, expected)
    print(f"t={t:<12} got={got} rfc={expected} {'OK' if ok else 'FAIL'}")

t = 1234567890
print("6-digit codes around t:")
for shift in (-30, 0, 30):
    print(f"  T{shift // 30:+d}: {totp(SECRET, t + shift, digits=6)}")

ছয়টি সারিই OK, অর্থাৎ কোডটি RFC-র মান হুবহু মিলিয়েছে, যেমন t=1234567890 got=89005924 rfc=89005924 OK. শেষ তিন লাইনে পাশের ধাপের code: T-1: 980357, T+0: 005924, T+1: 590587. একটি ধাপ এগোলেই পুরো সংখ্যা বদলে যায়। পরের অংশের window-র হিসাবে এই তিনটি code-ই লাগবে। আসল কাজে নিজে না লিখে পরীক্ষিত library ব্যবহার করুন। এই কোড শুধু বোঝার জন্য।

৪ · Verifier-এর দিক — window, replay, rate limit আর secret রাখা

Code বানানো সহজ অংশ। আসল নিরাপত্তা নির্ভর করে server যেভাবে যাচাই করে তার ওপর। ঘড়ি কখনো হুবহু মেলে না, আর code টাইপ করতেও সময় লাগে। তাই server শুধু বর্তমান ধাপ নয়, আশপাশের ধাপও দেখে। একে বলে verification window. RFC 6238 network দেরির জন্য বড়জোর এক ধাপ ছাড় দেওয়ার পরামর্শ দেয়।

নিয়মকেনভুল করলে কী হয়
Window ছোট রাখা (±১ ধাপ)ঘড়ির ছোট পার্থক্য সামলানোবড় window মানে বেশি code বৈধ
ব্যবহৃত ধাপ মনে রাখাReplay ঠেকানোদেখে নেওয়া code আবার চলে
ব্যর্থ চেষ্টা সীমিত করাছয় অঙ্ক অনুমান ঠেকানোসময় পেলে অনুমান সফল হবে
Secret encrypt করে রাখাDatabase ফাঁসে সুরক্ষাসব ব্যবহারকারীর code নকল করা যায়
Server-এর ঘড়ি NTP দিয়ে মেলানোসবার জন্য ঠিক হিসাবসঠিক code-ও বাতিল হয়

NIST SP 800-63B-4-এর ভাষায়, একটি OTP বৈধ থাকার সময়ে মাত্র একবার গ্রহণ করতে হবে, আর ব্যর্থ চেষ্টা সর্বোচ্চ ১০০-তে সীমিত রেখে authenticator বন্ধ করতে হবে। সংস্থা চাইলে আরও কম সীমা রাখতে পারে। নিচের simulator-এ simulated clock চলে, আর code-গুলো আগের Python block-এর একই test secret থেকে আগে হিসাব করে রাখা।

// simulated clock. আসল সময় নয়, code RFC test secret থেকে আগে হিসাব করা
const CODES = { 41152262: '980357', 41152263: '005924', 41152264: '590587',
  41152265: '240500', 41152266: '992085', 41152267: '687586' };
const STEP = 30, WINDOW = 1, MAX_FAILS = 5;
const user = { lastStep: 0, fails: 0, locked: false };

function fail(reason) {
  user.fails += 1;
  if (user.fails >= MAX_FAILS) user.locked = true;
  return `REJECT ${reason} (fails=${user.fails})`;
}
function verify(now, code) {
  if (user.locked) return 'REJECT locked, use recovery';
  const current = Math.floor(now / STEP);
  for (let w = -WINDOW; w <= WINDOW; w++) {
    const step = current + w;
    if (CODES[step] !== code) continue;   // real code: constant-time compare
    if (step <= user.lastStep) return fail('replay');
    user.lastStep = step; user.fails = 0;
    return `ACCEPT drift ${w >= 0 ? '+' : ''}${w}`;
  }
  return fail('invalid');
}
const T0 = 1234567890;
const events = [[0, '005924', 'on time'], [5, '005924', 'same code again'],
  [35, '240500', 'phone 1 step ahead'], [95, '590587', 'phone 2 steps behind'],
  [100, '240500', 'older used step'], [105, '992085', 'on time'],
  [110, '111111', 'guess'], [112, '222222', 'guess'], [114, '333333', 'guess'],
  [116, '444444', 'guess'], [118, '555555', 'guess'], [125, '687586', 'correct, late']];
for (const [dt, code, note] of events)
  console.log(`t0+${String(dt).padEnd(3)} ${code} ${note.padEnd(21)} ${verify(T0 + dt, code)}`);

প্রথম code গ্রহণের পরে একই code আবার দিলে REJECT replay (fails=1). এটিই RFC-র “একই code দ্বিতীয়বার নয়” নিয়ম। phone 1 step ahead window-র ভেতরে, তাই ACCEPT drift +1. phone 2 steps behind window-র বাইরে, তাই REJECT invalid. পরের সারিতে code window-র ভেতরে, কিন্তু আগে থেকেই ব্যবহৃত ধাপের, তাই REJECT replay. পাঁচটি অনুমানের শেষে REJECT invalid (fails=5), আর এরপরে সঠিক code-ও পায় REJECT locked, use recovery. খেয়াল করুন, lockout-এর একটি দাম আছে। অন্য কেউ ইচ্ছা করে ভুল দিয়ে আপনাকে আটকে রাখতে পারে। তাই বাস্তবে ক্রমবর্ধমান বিলম্ব আর ঝুঁকিভিত্তিক সিদ্ধান্ত মিলিয়ে ব্যবহার হয়। বিস্তারিত দেখুন rate limiting-এ।

হিসাব: ছয় অঙ্ক কতটা শক্ত

ধরুন window ±১, তাই একসঙ্গে ৩টি code বৈধ। ছয় অঙ্কে সম্ভাব্য মান ১০৬টি। এক অনুমানে সাফল্যের সম্ভাবনা p = 3 / 106 = 0.000003. n বার অনুমানে অন্তত একবার সফল হওয়ার সম্ভাবনা:

P = 1 − (1 − p)^n ≈ n × p (n × p ছোট হলে)
মোট অনুমান nPমানে
৫০.০০১৫%খুবই কম
১০০ (NIST-এর ঊর্ধ্বসীমা)০.০৩%তারপর authenticator বন্ধ
১০,০০০≈ ২.৯৬%Limit না থাকলে দ্রুত পৌঁছানো যায়
১০,০০,০০০≈ ৯৫.০%প্রায় নিশ্চিত, যদিও ১০০% নয়

শিক্ষাটি পরিষ্কার। ছয় অঙ্ক নিজে শক্ত নয়। শক্তি আসে rate limit থেকে। Limit মুছে দিলে TOTP-র গণিত আপনাকে বাঁচাবে না। Limit-টি অ্যাকাউন্ট ধরে রাখতে হবে, শুধু IP ধরে নয়, আর এক session-এর বদলে সব session মিলিয়ে গুনতে হবে। RFC 4226-ও ব্যর্থ চেষ্টা সীমিত করতে বলে।

Secret রাখবেন কোথায়

পর্ব ১৩-এ password hash করে রাখা শিখেছেন। TOTP secret-এর বেলায় তা চলে না। কেন? Server-কে প্রতিবার HMAC হিসাব করতে হয়, তাই আসল secret হাতে লাগে। OTP seed তাই ফেরত পড়া যায় এমনভাবে রাখতেই হয়। করণীয় হলো application key দিয়ে encrypt করে রাখা, আর সেই key KMS বা HSM-এ আলাদা রাখা। পর্ব ১৪-এর envelope encryption এখানে ভালো খাটে। Log, backup আর analytics-এ seed যেন না যায়। Enrollment-এর পরে সেটি আর কখনো দেখানো উচিত নয়। Database আর key দুটি একসঙ্গে ফাঁস হলে কী হবে? সব ব্যবহারকারীর seed বদলাতে হবে। আগেই সেই পরিকল্পনা রাখুন।

৫ · Push approval, MFA fatigue আর number matching

Code টাইপ করা ঝামেলার। তাই এলো push approval: login করলেই ফোনে বার্তা আসে, “আপনি কি login করছেন?” একটি চাপেই কাজ শেষ। সুবিধাটি বড়। কিন্তু সেই সহজ বোতামটিই দুর্বলতা।

রাত দুইটায় বাসার কলিংবেল বারবার বাজছে। দারোয়ান ঘুমের ঘোরে একসময় বিরক্ত হয়ে গেট খুলে দিলেন, পরিচয়পত্র না দেখেই। MFA fatigue ঠিক এমন। Password হাতে থাকা কেউ বারবার login করে, আর ব্যবহারকারীর ফোনে একের পর এক অনুরোধ আসে। ক্লান্ত হয়ে বা ভুলে কেউ “হ্যাঁ” চেপে দেন।

২০২২ সালের Uber ঘটনার প্রকাশিত বিবরণগুলোতে বারবার push পাঠিয়ে ক্লান্ত করার কথা আসে, যদিও খুঁটিনাটি নিয়ে সূত্রভেদ আছে। শিক্ষাটি নির্দিষ্ট ঘটনার চেয়ে বড়: “অনুমোদন” চাপাটি যদি চিন্তা ছাড়াই করা যায়, তাহলে মানুষ চিন্তা ছাড়াই করবেন।

প্রতিকার: Number matching

Login পর্দায় একটি ছোট সংখ্যা দেখায়, আর ব্যবহারকারীকে ফোনে সেটি টাইপ করতে হয়। পর্দার সামনে না থাকলে সংখ্যাটি জানার উপায় নেই। ফলে হঠাৎ আসা অনুরোধে অন্ধ অনুমোদন সম্ভব হয় না। CISA ২০২২ সালের অক্টোবরে এটিকে push-ভিত্তিক MFA-র অন্তর্বর্তী প্রতিকার হিসেবে সুপারিশ করে, আর প্রথম পছন্দ রাখে phishing-প্রতিরোধী MFA.

নকশার খুঁটিনাটি গুরুত্বপূর্ণ। NIST SP 800-63B-4 বলে, শুধু দুটি মান মিলিয়ে “অনুমোদন” চাপা আর যথেষ্ট নয়, কারণ মানুষ না মিলিয়েই চাপতে পারেন। কয়েকটি বিকল্পের তালিকা থেকে বাছাইও যথেষ্ট নয়। মানটি এক channel থেকে আরেকটিতে সত্যিই স্থানান্তর করতে হবে। NIST push-এর সংখ্যা বা হারও সীমিত রাখতে বলে।

মূল ধারণা

Number matching বিরক্তি থেকে আসা অনুমোদন ঠেকায়, প্রতারণা থেকে আসা অনুমোদন নয়। নকল সাইট পর্দায় সংখ্যাটি দেখালে ব্যবহারকারী ভেবেই নিতে পারেন যে সব ঠিক আছে, আর ফোনে সেটি টাইপ করে দিতে পারেন। NIST স্পষ্ট বলে, out-of-band authentication phishing-প্রতিরোধী নয়।

Detection: কী দেখবেন

অল্প সময়ে একই ব্যবহারকারীর অনেক push প্রত্যাখ্যান, তারপর হঠাৎ একটি অনুমোদন একটি শক্ত সংকেত। ব্যবহারকারীর জন্য “এটি আমি নই” বোতাম রাখুন, যা সরাসরি SOC-তে সতর্কবার্তা পাঠাবে। নতুন authenticator যোগ হওয়ার ঘটনাও গুরুত্ব দিয়ে দেখুন। অনেক সময় অনুপ্রবেশকারী প্রথম যে কাজটি করে, তা হলো নিজের জন্য একটি পদ্ধতি যোগ করা। নিচের rule-টি Sigma ধাঁচের উদাহরণ, log-এর নামগুলো কাল্পনিক। Sigma আর correlation-এর বিস্তারিত পর্ব ৫৬-তে।

# উদাহরণ: কাল্পনিক identity log schema, আপনার নিজের system-এর জন্য বদলে নিন
title: New MFA Method Added Without Recent Step-Up
id: 6f0c2a54-7b1e-4c1d-9a3e-000000000016
status: experimental
description: A new authenticator was added without a recent strong re-check.
logsource:
  product: example_idp
  category: authentication
detection:
  selection:
    event_type: mfa.factor.added
    recent_step_up: false
  condition: selection
falsepositives:
  - First enrollment by a new employee
level: high

৬ · Real-time phishing relay আর origin binding

এতক্ষণ যা দেখলেন, সব পদ্ধতিতে একটি মিল আছে। ব্যবহারকারী নিজে একটি মান এক জায়গা থেকে পড়ে অন্য জায়গায় দেন। সেই “অন্য জায়গা” যে আসল সাইট, তা যাচাই করে শুধু তাঁর চোখ। Phishing-এ ঠিক এই চোখকেই ঠকানো হয়।

পুরোনো ধারণা ছিল, OTP ৩০ সেকেন্ডে বদলায়, তাই চুরি করে লাভ নেই। Real-time phishing relay এই ধারণা ভেঙে দিয়েছে। এটি ধারণাগতভাবে পথের মাঝে বসা একটি মধ্যস্থতাকারী (MITM-এর এক রূপ)। ব্যবহারকারী নকল পাতায় যা দেন, তা সঙ্গে সঙ্গে আসল সাইটে যায়। ৩০ সেকেন্ড অনেক লম্বা সময়। OTP একটি সাধারণ সংখ্যা, তাতে লেখা নেই সে কোন সাইটের। তাই আসল সাইট তাকে সঠিকই পায়।

একটি নকল ব্যাংকের কাউন্টারের কথা ভাবুন। আপনি চেকে সই করে দিলেন, আর কাউন্টারের লোক দৌড়ে আসল ব্যাংকে গিয়ে টাকা তুলে নিলেন। সইটি খাঁটি, তাই আসল ব্যাংকের আপত্তি নেই। এবার ভাবুন, প্রতিটি চেকে ব্যাংকের নাম আর শাখা ছাপা থাকে, আর সেটি বদলালেই সই বাতিল। নকল কাউন্টারে দেওয়া সই আসল ব্যাংকে কোনো কাজে আসবে না। এই ছাপাটিই origin binding.

Origin মানে scheme, host আর port-এর মিলিত পরিচয়, যেমন https://shop.example.com. পর্ব ৩৬-এ browser-এর দিক থেকে এটি আবার আসবে। Origin binding-এ দুটি কাজ হয় একসঙ্গে। মানুষের বদলে browser origin পড়ে, আর সেই origin স্বাক্ষরের ভেতরে চলে যায়।

চোখের বদলে browser যাচাই করে

Origin binding: the browser, not the user, reads the site name

Origin binding: আসল আর নকল সাইটের ফলাফল আসল সাইট shop.example.com নকল সাইট shop.example.net Browser origin নিজে লেখে, পাতা বদলাতে পারে না Authenticator passkey বাঁধা: shop.example.com স্বাক্ষর মিলল login সফল এই সাইটের passkey নেই কিছুই পাওয়া গেল না
ছবি ১৬.১ — মানুষের চোখ .net আর .com গুলিয়ে ফেলতে পারে, browser পারে না।

NIST SP 800-63B-4 phishing resistance-কে দুই ভাবে পাওয়ার কথা বলে। Channel binding-এ authenticator-এর ফল ওই নির্দিষ্ট সংযোগের সঙ্গে বাঁধা থাকে। উদাহরণ হলো client-authenticated TLS, যা পর্ব ১২-এ mTLS নামে দেখেছেন। Verifier name binding-এ ফল যাচাইকারীর নামের সঙ্গে বাঁধা থাকে। উদাহরণ WebAuthn. নিয়মটি স্পষ্ট: যেসব পদ্ধতিতে মানুষ হাতে ফল টাইপ করেন, যেমন OTP, সেগুলো phishing-প্রতিরোধী নয়।

নিচের ডায়াগ্রামে একই নকল পাতায় দুজন ব্যবহারকারীকে পাশাপাশি দেখুন। একজন OTP ব্যবহার করেন, অন্যজন passkey.

একই নকল পাতা, দুই ধরনের login
Browser-এর ঠিকানা
OTP ব্যবহারকারী
Passkey ব্যবহারকারী
নকল সাইটের হাতে
  1. নকল ঠিকানা। ঠিকানাটি shop.example.net, আসলটি shop.example.com. দেখতে প্রায় এক। দুই ব্যবহারকারীই পার্থক্য ধরতে পারলেন না। মানুষের ভুল এখানে স্বাভাবিক, তাই নকশা মানুষের সতর্কতার ওপর নির্ভর করতে পারে না।
  2. Password. Password দিলে সেটি ফাঁস হলো, দুজনেরই। Passkey-only account-এ এই ধাপটিই থাকে না, তাই ফাঁসের মতো কিছু থাকে না।
  3. দ্বিতীয় ধাপ। OTP ব্যবহারকারী নিজের হাতে 005924 টাইপ করলেন। Passkey ব্যবহারকারীর বেলায় browser দেখল, পাতার origin আর চাওয়া RP নাম মেলে কি না। এখানে মানুষের কোনো সিদ্ধান্ত নেই।
  4. Code পৌঁছাল, credential মিলল না। Code-এ সাইটের নাম নেই, তাই relay-র মাধ্যমে আসল সাইটে সেটি বৈধ। অন্যদিকে authenticator-এ shop.example.net-এর কোনো credential নেই।
  5. ফল আলাদা হয়ে গেল। OTP সফল, তাই login-এর পরের session ভুল হাতে যেতে পারে। Passkey-র পথে স্বাক্ষরই তৈরি হয়নি, তাই relay-র পাঠানোর মতো কিছু নেই।
  6. রক্ষকের শিক্ষা। Passkey ব্যবহারকারীর ক্ষতি সীমিত। তবু password বদলান, আর দেখুন সেই account-এ SMS-এ নামার বিকল্প খোলা আছে কি না। খোলা থাকলে নকল সাইট সেদিকেই ঠেলে দিতে পারে। তাই passkey-র পাশে দুর্বল fallback রাখা চলে না।

এটি শুধু তত্ত্ব নয়। ২০২২ সালের আগস্টে Cloudflare জানায়, কর্মীদের কাছে একটি সুসংগঠিত SMS phishing প্রচারণা আসে, আর তিনজন কর্মী নকল পাতায় তথ্য দিয়ে ফেলেন। তবু login হয়নি, কারণ প্রতিষ্ঠানটি FIDO2 hardware key বাধ্যতামূলক করেছিল। তাদের প্রতিবেদনের ভাষ্যে origin binding-ই real-time phishing আটকেছে। Google-ও ২০১৮ সালে জানায়, ২০১৭ সালের শুরুতে কর্মীদের security key দেওয়ার পর কোনো নিশ্চিত account takeover তাদের জানা ছিল না। এগুলো প্রতিষ্ঠানের নিজের ভাষ্য, স্বাধীনভাবে নিরীক্ষিত সংখ্যা নয়।

৭ · FIDO2, WebAuthn আর CTAP — registration আর login ceremony

নামগুলো গুলিয়ে যায়, তাই আগে সাজিয়ে নিই। FIDO2 হলো ছাতা-নাম, যার দুটি অংশ। WebAuthn হলো W3C-র মান, অর্থাৎ website আর browser-এর ভাষা। CTAP হলো FIDO Alliance-এর মান, অর্থাৎ browser বা OS আর বাইরের যন্ত্রের ভাষা। যে যন্ত্র key রাখে আর স্বাক্ষর করে, সে authenticator. ল্যাপটপ বা ফোনের ভেতরের হলে platform authenticator, আর USB, NFC বা Bluetooth-এ যুক্ত আলাদা চাবি হলে security key. যে website login নিচ্ছে, সে relying party বা RP. তার নাম RP ID, যেমন shop.example.com.

WebAuthn-এ পুরো অনুষ্ঠানকে বলে ceremony. ভিত্তি হলো পর্ব ১০-এর public key cryptography আর পর্ব ১১-এর digital signature. গোপন key কখনো server-এ যায় না। এটিই shared secret-এর সঙ্গে মৌলিক পার্থক্য।

Registration: key জোড়া তৈরি

কোন key কোথায় থাকে

Registration: private key stays with the authenticator, public key goes to the server

Registration-এর পরে key-র অবস্থান Authenticator Private key: বাইরে পড়া যায় না আঙুলের ছাপ বা PIN: যন্ত্রেই যাচাই Server-এর database Public key, credential ID, RP ID Sign count, backup flag ফাঁস হলেও এ দিয়ে login হয় না শুধু public key যায়
ছবি ১৬.২ — TOTP-তে server-এর কাছে login-এর ক্ষমতা থাকে। Passkey-তে থাকে শুধু যাচাইয়ের ক্ষমতা।
  1. Server একটি random challenge, RP ID আর ব্যবহারকারীর পরিচয় পাঠায়।
  2. Browser origin মিলিয়ে authenticator-কে বলে নতুন key জোড়া বানাতে। ব্যবহারকারী আঙুলের ছাপ বা PIN দেন। এটি user verification.
  3. Authenticator ফেরত দেয় credential ID আর public key, সঙ্গে চাইলে attestation, মানে যন্ত্রের ধরন সম্পর্কে একটি স্বাক্ষরিত বিবৃতি।
  4. Server challenge, origin আর RP ID-র hash মিলিয়ে public key রেখে দেয়।

Login-এর ধাপগুলো এবার দেখুন। মানগুলো উদাহরণ, তবে rpIdHash সত্যিই shop.example.com-এর SHA-256. Script চালিয়ে পাওয়া।

  1. ServerchallengeRP
  2. Browseroriginনাম যাচাই
  3. Authenticatorsignatureস্বাক্ষর
  4. Serververifyযাচাই
Server → Browserএই login-এর জন্য নতুন
challenge: example-challenge
rpId     : shop.example.com
timeout  : 60000 ms
clientDataJSONBrowser নিজে লেখে
{
  "type": "webauthn.get",
  "challenge": "ZXhhbXBsZS1...",
  "origin": "https://shop.example.com",
  "crossOrigin": false
}
Authenticatorস্থানীয় যাচাই
credential খোঁজা: shop.example.com → পাওয়া গেছে
user presence    : UP = 1
user verification: UV = 1 (আঙুলের ছাপ)
আঙুলের ছাপ server-এ যায় না
SignaturePrivate key দিয়ে
rpIdHash = 951623a26f8b3388...
flags    = UP, UV, BE, BS
signCount= 0

sign( authenticatorData ||
      SHA-256(clientDataJSON) )
Server-এর যাচাইসব মিললে তবেই
type      == webauthn.get        ✓
challenge == পাঠানো মান          ✓
origin    == অনুমোদিত তালিকায়    ✓
rpIdHash  == SHA-256(rpId)       ✓
UP, UV    == নীতি অনুযায়ী        ✓
signature == public key-তে মিলল  ✓
ফলLogin শেষ
challenge বাতিল (একবারই চলবে)
session তৈরি
event লেখা: login, credential ID, UV
  1. Challenge. Server প্রতি login-এর জন্য নতুন random challenge বানায়। এটি অল্প সময়ের জন্য বৈধ। পুরোনো স্বাক্ষর তাই আবার চালানো যায় না, যা পর্ব ৯-এর replay ঠেকানোর ভাবনা। TOTP-র মতো ঘড়ি মেলানোর দরকারও এখানে পড়ে না।
  2. Browser origin লেখে। পাতা RP ID দাবি করে, আর browser দেখে সেটি পাতার origin-এর সঙ্গে মেলে কি না। না মিললে অনুরোধ থেমে যায়। clientDataJSON পাতা নয়, browser বানায়। এখানেই origin স্বাক্ষরের উপাদানে ঢোকে।
  3. Authenticator credential খোঁজে। RP ID ধরে খোঁজা হয়। মিললে যন্ত্র ব্যবহারকারীর উপস্থিতি (user presence, UP) আর পরিচয় (UV) যাচাই করে। আঙুলের ছাপ যন্ত্রের ভেতরেই থাকে। PIN-ও server-এ যায় না। এখানে PIN মানে যন্ত্র খোলার স্থানীয় চাবি।
  4. স্বাক্ষর। Authenticator authenticatorData তৈরি করে। এতে আছে RP ID-র SHA-256 (951623a2…), flags আর sign count. তারপর এর সঙ্গে clientDataJSON-এর hash জুড়ে private key দিয়ে স্বাক্ষর করে। Origin, challenge, সব এখন স্বাক্ষরের নিচে।
  5. Server যাচাই। ছয়টি প্রশ্নের প্রতিটির উত্তর “হ্যাঁ” হতে হবে। একটি বাদ দিলেও সুরক্ষা ভাঙে। বিশেষ করে origin আর challenge যাচাই বাদ দিলে origin binding-এর পুরো লাভ শেষ। তাই নিজে না লিখে পরীক্ষিত library ব্যবহার করুন।
  6. Session. Challenge বাতিল হয়, session তৈরি হয়, ঘটনা log-এ যায়। এর পরের নিরাপত্তা আর passkey-র হাতে নেই, session-এর হাতে। সে কথা পর্ব ১৭-তে।

Website-এর দিক থেকে ডাকটি কেমন দেখায়, তা নিচে। এটি আপনার নিজের সাইটের জন্য নমুনা, চালানোর জন্য নয়। আপনার server থেকে আনা challenge ছাড়া এটি অর্থহীন।

// উদাহরণ: challengeBytes আপনার server থেকে আসবে, এখানে বানানো যাবে না
const assertion = await navigator.credentials.get({
  publicKey: {
    challenge: challengeBytes,
    rpId: "shop.example.com",
    userVerification: "required",
    timeout: 60000
  }
});
// assertion পুরোটা server-এ পাঠান। যাচাই browser-এ নয়, server-এ হবে।

এবার একটি ছোট খেলনায় দেখুন, কোন যাচাই কোন বিপদ ধরে। এখানে স্বাক্ষর খেলনা, কিন্তু কাঠামোটি একই। Private key শুধু authenticator-এর হাতে, আর server-এর কাছে শুধু public মান।

// খেলনা স্বাক্ষর: ছোট RSA (n=3233) + FNV hash. real নয়, শুধু ধারণার জন্য
const N = 3233, E = 17, D = 2753, RP = 'shop.example.com';
const ORIGIN = 'https://' + RP;
function modPow(b, e, m) { let r = 1; b %= m;
  while (e > 0) { if (e & 1) r = r * b % m; b = b * b % m; e >>= 1; }
  return r; }
function toyHash(s) { let h = 2166136261;
  for (const c of s) h = Math.imul(h ^ c.charCodeAt(0), 16777619) >>> 0;
  return h % N; }
const toySign = (rp, data) => modPow(toyHash(rp + '|' + data), D, N);
const wallet = new Set([RP]);                  // passkey শুধু এই RP-র জন্য
function browserGet(pageHost, challenge) {     // origin browser নিজে লেখে
  const data = JSON.stringify({ origin: 'https://' + pageHost, challenge });
  if (!wallet.has(pageHost)) return null;      // এই সাইটের credential নেই
  return { data, sig: toySign(pageHost, data) };
}
function serverVerify(resp, challenge) {       // server জানে শুধু N আর E
  if (!resp) return 'nothing to verify, no signature exists';
  const cd = JSON.parse(resp.data);
  if (modPow(resp.sig, E, N) !== toyHash(RP + '|' + resp.data))
    return 'REJECT signature';
  if (cd.challenge !== challenge) return 'REJECT stale challenge';
  if (cd.origin !== ORIGIN) return 'REJECT origin ' + cd.origin;
  return 'ACCEPT';
}
const good = browserGet(RP, 'c1');
console.log('real site      :', serverVerify(good, 'c1'));
console.log('look-alike site:', serverVerify(browserGet('shop.example.net', 'c2'), 'c2'));
console.log('old response   :', serverVerify(good, 'c3'));
const edited = { data: good.data.replace('c1', 'c3'), sig: good.sig };
console.log('edited data    :', serverVerify(edited, 'c3'));
const fakeData = JSON.stringify({ origin: 'https://shop.example.net', challenge: 'c4' });
console.log('buggy wallet   :', serverVerify({ data: fakeData, sig: toySign(RP, fakeData) }, 'c4'));

প্রথম লাইনে আসল সাইট ACCEPT. নকল সাইটে nothing to verify, no signature exists, কারণ credential না থাকায় স্বাক্ষরই হয়নি। পুরোনো উত্তর নতুন login-এ REJECT stale challenge. লেখা বদলালে REJECT signature, কারণ বদলানো লেখায় স্বাক্ষর মেলে না। শেষ সারিটি ধরে নেওয়া একটি ত্রুটিপূর্ণ wallet, যে ভুল origin-এ সই করেছে। তখনও server ধরে: REJECT origin https://shop.example.net. প্রতিটি যাচাই আলাদা একটি বিপদ ধরে, তাই একটিও বাদ দেওয়া চলে না। এই খেলনা স্বাক্ষর ভাঙা খুব সহজ, আসল ব্যবস্থায় থাকে ES256-এর মতো আধুনিক algorithm.

আরও গভীরে: RP ID হতে হবে পাতার domain বা তার ওপরের নিবন্ধনযোগ্য domain, তাই login.example.com পাতা example.com-কে RP ID বলতে পারে। WebAuthn Level 3 ২০২৬ সালের ২৫ আগস্ট W3C Recommendation হয়, আর এতে সম্পর্কিত origin-এর ব্যবস্থাও আছে। FIDO-র মান হিসেবে CTAP 2.2-তে কাছের ফোনকে authenticator হিসেবে ব্যবহারের hybrid পথ আছে, যা hybrid transport নামে পরিচিত। এখানে QR code আর Bluetooth নৈকট্য মিলে দূর থেকে relay করা কঠিন করে। Sign count ক্লোন ধরতে সাহায্য করতে পারে, তবে অনেক synced passkey সবসময় ০ পাঠায়, তাই এটি নিশ্চিত সংকেত নয়।

৮ · Passkey — synced, device-bound আর recovery-র দুর্বলতা

Passkey হলো FIDO credential-এর জনপ্রিয় নাম, যা দিয়ে password ছাড়াই login করা যায়। যন্ত্র নিজেই জানে কোন সাইটের জন্য কোন key, এমন credential-কে বলে discoverable credential. আঙুলের ছাপ বা PIN দিলে একসঙ্গে দুটি জিনিস প্রমাণ হয়: যন্ত্রটি আপনার কাছে আছে, আর আপনি সেটি খুলতে পারেন। তাই একটি ধাপেই MFA-র মান পাওয়া যায়।

Passkey দুই ধরনের। পার্থক্যটি হলো private key কোথায় থাকতে পারে।

বিষয়Synced passkeyDevice-bound passkey
Key কোথায়ব্যবহারকারীর যন্ত্রগুলোতে, cloud account-এর মাধ্যমে encrypted অবস্থায় syncএকটি যন্ত্র বা security key-র ভেতরে, বের করা যায় না
ফোন হারালেঅন্য যন্ত্রে সাধারণত থাকেদ্বিতীয় key বা recovery লাগে
নতুন ঝুঁকিSync provider-এর account নিরাপত্তা, শেয়ারের সম্ভাবনাহারানো, ভাঙা, ব্যবহারে ঝামেলা
PhishingOrigin binding একই থাকেOrigin binding একই থাকে
NIST-এর স্তরAAL2 পর্যন্তAAL3-তে যোগ্য হতে পারে (অন্য শর্তসাপেক্ষে)
উপযুক্তসাধারণ গ্রাহক, বড় জনগোষ্ঠীAdmin, উচ্চ ঝুঁকির কর্মী

WebAuthn-এর flags-এ BE (sync হতে পারে কি না) আর BS (এখন backup হয়েছে কি না) জানানো হয়। Server এ দিয়ে নীতি ঠিক করতে পারে, যেমন উচ্চ ঝুঁকির কর্মীদের device-bound key দাবি করা। তবে NIST বলে, সাধারণ মানুষের সেবায় BS-এর ভিত্তিতে গ্রহণ-বর্জন করা উচিত নয়। সাধারণ গ্রাহকের জন্য হিসাবটি সহজ: password আর OTP-র চেয়ে synced passkey অনেক ভালো, তবে তার নিরাপত্তা sync account-এর নিরাপত্তার সঙ্গে জড়িত।

Recovery: আসল দুর্বল জায়গা

একটি চিন্তার পরীক্ষা করুন। আপনার সেবায় passkey আছে, phishing আটকে যায়। ব্যবহারকারী ফোন হারিয়ে ফেললেন। এবার কী? Account recovery যদি শুধু SMS code বা কয়েকটি ব্যক্তিগত প্রশ্ন হয়, তাহলে আপনার সব নিরাপত্তা সেই প্রশ্নের সমান। হামলাকারী তালা ভাঙে না, পেছনের দরজা খোঁজে।

ভল্টের দরজা ইস্পাতের, কিন্তু চাবি হারালে দারোয়ানকে “ভাই, ভুলে গেছি” বললেই পাশের দরজা খুলে দেন। তাহলে আসল নিরাপত্তা দরজায় নয়, দারোয়ানের নিয়মে।

  • Backup code: আগে থেকে দেওয়া একবার ব্যবহারযোগ্য code. কাগজে ছাপিয়ে নিরাপদ জায়গায় রাখুন, password-এর পাশে নয়।
  • একাধিক authenticator: শুরুতেই দুটি passkey বা security key যোগ করা। এটিই সবচেয়ে ভালো recovery, কারণ recovery দরকারই পড়ে না।
  • Helpdesk-এর নিয়ম: কথায় বিশ্বাস নয়। পরিচয় যাচাইয়ের লিখিত ধাপ, দ্বিতীয় ব্যক্তির অনুমোদন আর log. পর্ব ৩-এর separation of duties এখানে কাজে লাগে।
  • জানানো আর অপেক্ষা: Recovery হলে সব জায়গায় notification পাঠানো। স্পর্শকাতর কাজে কিছু সময় বিরতি রাখা।

NIST SP 800-63B-4-এর নিয়মগুলো কার্যকর মাপকাঠি। সংরক্ষিত recovery code-এ অনুমোদিত random উৎস থেকে অন্তত ৬৪ bit থাকতে হবে, code hash করে রাখতে হবে, আর ব্যবহারের পরে বাতিল করতে হবে। Recovery হলে সবসময় ব্যবহারকারীকে জানাতে হবে। AAL2 account-এ recovery-র জন্য বিভিন্ন পথের সমন্বয় লাগে, যেমন ভিন্ন পদ্ধতিতে পাওয়া দুটি recovery code.

হিসাব: Backup code-এ কত bit

Code-এর রূপহিসাবEntropy৬৪ bit?
৮ অঙ্কের সংখ্যা8 × log₂10≈ ২৬.৬ bitনা
১০ অঙ্কের সংখ্যা10 × log₂10≈ ৩৩.২ bitনা
১৬ hex অক্ষর16 × 4৬৪ bitহ্যাঁ, ঠিক সীমায়
১৩ Base32 অক্ষর13 × 5৬৫ bitহ্যাঁ
২০ অঙ্কের সংখ্যা20 × log₂10≈ ৬৬.৪ bitহ্যাঁ

৬৪ bit পেতে দশমিকে দরকার ⌈64 / 3.32⌉ = ২০ অঙ্ক। ধারণাটি পর্ব ৭-এর entropy-র। অক্ষরগুলো নিরাপদ CSPRNG থেকে এলে তবেই এই হিসাব খাটে।

৯ · প্রতিষ্ঠানে চালু করা — enrollment, step-up আর NIST-এর মান

একটি কাল্পনিক অনলাইন বাজারের নিরাপত্তা প্রধান আপনি। কাল থেকে সবার passkey চালু করে দিলে কী হবে? Helpdesk ভেঙে পড়বে, আর পুরোনো ফোনের মানুষ আটকে যাবেন। Rollout একটি প্রকৌশল আর মানুষ সামলানোর কাজ।

Enrollment: নতুন পদ্ধতি যোগ করার মুহূর্তটিই ঝুঁকির

কেউ password চুরি করে নিজের যন্ত্র যোগ করে ফেললে সব শেষ। তাই নতুন authenticator যোগ করার আগে বিদ্যমান শক্ত পদ্ধতিতে আবার যাচাই করুন, ব্যবহারকারীকে জানান, আর ঘটনাটি log করুন। প্রথম enrollment-ও গুরুত্বপূর্ণ। কেউ যেন শুধু password দিয়ে অন্যের account-এ প্রথম passkey বসাতে না পারে।

Step-up authentication: ঝুঁকি বুঝে যাচাই

প্রতিটি পাতায় আঙুলের ছাপ চাইলে মানুষ বিরক্ত হন। আবার login-এর পরে সব খোলা রাখাও ঠিক নয়। সমাধান হলো সংবেদনশীল কাজের আগে নতুন করে যাচাই করা: নতুন প্রাপক যোগ, বড় লেনদেন, password বা MFA বদল, ডেটা export, admin ভূমিকা নেওয়া। লেনদেনের ক্ষেত্রে সবচেয়ে ভালো হলো যাচাইকে নির্দিষ্ট লেনদেনের সঙ্গে বাঁধা, যাতে ব্যবহারকারী পরিমাণ আর প্রাপক দেখে অনুমোদন দেন। Admin-দের নিয়ম পর্ব ২০-এ আছে।

Rollout-এর ক্রম

  1. তালিকা: কোন system কোন login নেয়, কোনগুলো পুরোনো protocol-এ আটকে আছে।
  2. আগে admin: সবচেয়ে বড় blast radius-এর হিসাব আগে রক্ষা করুন, প্রতিজনের জন্য দুটি device-bound key.
  3. Break-glass: জরুরি হিসাব আলাদা রাখুন, ব্যবহারে সতর্কবার্তা বাজান, নিয়মিত পরীক্ষা করুন।
  4. পরীক্ষামূলক দল: একটি ছোট বিভাগে চালু করে সমস্যা শিখুন।
  5. পর্যায়ে পর্যায়ে বাধ্যতামূলক: আগে ঐচ্ছিক, তারপর নতুন কর্মীদের জন্য, তারপর সবার জন্য।
  6. দুর্বল fallback বন্ধ: এটিই শেষ এবং সবচেয়ে ভুলে যাওয়া ধাপ। SMS খোলা থাকলে হামলাকারী সেখানেই নামতে চাইবে।

Metric রাখুন: কত শতাংশ account-এ phishing-প্রতিরোধী পদ্ধতি আছে, কত login fallback দিয়ে হচ্ছে, মাসে কতবার helpdesk recovery হচ্ছে, push প্রত্যাখ্যানের সংখ্যা। সবচেয়ে কাজের সংখ্যাটি হলো fallback-এর হার। এটি না কমলে নিরাপত্তা কাগজে বেড়েছে, বাস্তবে নয়।

NIST-এর স্তর

AAL মানে Authentication Assurance Level. NIST SP 800-63B-4 (২০২৫, 800-63B-এর আগের সংস্করণের স্থলাভিষিক্ত) থেকে মূল বিষয়গুলো হলো:

স্তরPhishing resistanceSyncable authenticator
AAL1আবশ্যক নয়চলে
AAL2Verifier-কে অন্তত একটি phishing-প্রতিরোধী বিকল্প দিতে হবে, আর উৎসাহিত করা উচিতচলে, sync account AAL2-সমতুল্য MFA দিয়ে সুরক্ষিত থাকতে হবে
AAL3Phishing-প্রতিরোধী authenticator আবশ্যকচলে না, key export করা যাবে না

এখানে একটি সূক্ষ্মতা আছে। NIST-এর syncable appendix অনুযায়ী phishing resistance সুপারিশকৃত, আর মার্কিন federal enterprise-এর জন্য আবশ্যক। কারণ এটি সঠিক কনফিগারেশনের ওপর নির্ভর করে। আবার নকল সাইট ঠেকানোর দিক থেকে synced আর device-bound passkey একই। কিন্তু sync account দখল ঠেকানোর দিক থেকে তারা এক নয়। “Phishing-প্রতিরোধী” শব্দটি দেখে সব ঝুঁকি শেষ ভাববেন না। মার্কিন সরকারের OMB M-22-09 (২০২২) সরকারি কর্মীদের জন্য phishing-প্রতিরোধী MFA চেয়েছিল। বাংলাদেশে আপনার খাতের নিয়ন্ত্রকের বর্তমান নিয়ম আলাদাভাবে দেখে নিন।

পরীক্ষা ও ইন্টারভিউতে: এ ধরনের প্রশ্ন আসতে পারে।
১. TOTP আর HOTP-র পার্থক্য? HOTP-তে counter, TOTP-তে সময় ÷ time step. ভিত্তি একই HMAC.
২. OTP কেন phishing ঠেকায় না? এটি সাইটের নামের সঙ্গে বাঁধা নয়, তাই relay করা যায়।
৩. TOTP seed hash করা যায় না কেন? Server-কে প্রতিবার HMAC হিসাব করতে হয়, তাই আসল secret লাগে।
৪. Passkey-তে database ফাঁস হলে? শুধু public key ফাঁস হয়, তা দিয়ে login হয় না।
৫. Number matching কী ঠেকায়? Push fatigue-র অন্ধ অনুমোদন ঠেকায়, phishing নয়।

১০ · AI-এর যুগে MFA — যা যাচাই না করলে বিপদ

AI দ্রুত TOTP বা WebAuthn কোড লিখে দেয়। কোড চলেও। কিন্তু এখানকার ভুলগুলো প্রায়ই “চলে” এমন ভুল: login সফল হয়, শুধু সুরক্ষাটি থাকে না। Happy path পরীক্ষায় তা ধরা পড়ে না।

AI-এর সম্ভাব্য ভুলবিপদযাচাই
“SMS OTP phishing ঠেকায়” বলাভুল নিরাপত্তাবোধNIST-এর মূল লেখা পড়া
Window ±১০ দিয়ে “ঘড়ির সমস্যা” মেটানোবৈধ code অনেক বেড়ে যায়Window-র মান পর্যালোচনা
ব্যবহৃত ধাপ মনে না রাখাReplay চলেএকই code দুবার দিয়ে test
Seed plain লেখায় database বা log-এ রাখাসব ব্যবহারকারীর code নকলSchema আর log পর্যালোচনা
Origin বা challenge যাচাই বাদ দেওয়াOrigin binding নিষ্ফলভুল origin দিয়ে নেতিবাচক test
বানানো NIST ধারা বা CVE নম্বরভুল সিদ্ধান্তপ্রাথমিক উৎসে নিজে খোঁজা
verify=False দিয়ে IdP সংযোগ “ঠিক” করাTLS যাচাই বন্ধDiff পর্যালোচনা, কারণ ঠিক করা

নিচের prompt AI-কে পর্যালোচকের ভূমিকায় রাখে। আসল secret, seed, token বা গ্রাহকের ডেটা prompt-এ দেবেন না।

তুমি একজন defensive security reviewer. নিচে আমার নিজের application-এর TOTP আর WebAuthn যাচাইয়ের কোড আছে (secret বাদ দিয়ে দিয়েছি)। ১. window, replay সুরক্ষা, rate limit আর constant-time তুলনা দেখো। ২. WebAuthn-এ type, challenge, origin, rpIdHash, UP/UV আর signature যাচাই আছে কি না দেখো। ৩. seed কীভাবে রাখা হচ্ছে, log-এ যাচ্ছে কি না দেখো। ৪. প্রতিটি সমস্যার জন্য একটি নেতিবাচক test case দাও। ৫. যেকোনো standard উল্লেখ করলে নাম আর ধারা দাও, নিশ্চিত না হলে "নিশ্চিত নই" বলো। বানিয়ে কিছু বলবে না। [এখানে আপনার কোড]

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।

প্র ০১SMS OTP-র এত সমালোচনা, তবু ব্যাংক আর সেবাদাতারা এটি ছাড়ছে না কেন?

ইতিহাস দিয়ে শুরু করি। ২০১৬ সালের জুলাইয়ে NIST-এর 800-63B খসড়ায় SMS-কে deprecated বলা হয়, অর্থাৎ ভবিষ্যতে বাদ পড়তে পারে। শিল্পজগতে আলোড়ন ওঠে। ২০১৭ সালের চূড়ান্ত সংস্করণে শব্দটি নরম হয়ে restricted হয়। ২০২৫ সালের SP 800-63B-4-ও phone network-কে একটিমাত্র restricted authenticator হিসেবে রেখেছে। অর্থাৎ প্রায় দশ বছর পরেও মানদণ্ড সংস্থা বলছে “ঝুঁকিপূর্ণ”, “নিষিদ্ধ” বলছে না। কেন?

  • নাগাল: SMS কোনো app ছাড়াই সাধারণ ফোনে চলে। কম দামের ফোন ব্যবহার করেন, এমন বিপুল মানুষকে বাদ দিলে নিরাপত্তা নয়, বঞ্চনা বাড়ে।
  • পরিচিতি: মানুষ এটি বোঝেন। নতুন পদ্ধতি শেখাতে খরচ লাগে, helpdesk-এর চাপও বাড়ে।
  • তুলনা: ঝুঁকি মাপতে হয় বিকল্পের সঙ্গে। শুধু password-এর চেয়ে SMS OTP স্বয়ংক্রিয় credential stuffing অনেকটা ঠেকায়।

তবে এটি স্থায়ী উত্তর নয়। ভালো নকশায় SMS শুধু একটি স্তর। সেবাদাতা SIM বদলের সংকেত দেখে, লেনদেনের ধরন দেখে, নতুন যন্ত্রকে সন্দেহ করে। আর যাঁদের স্মার্টফোন আছে, তাঁদের ধীরে ধীরে শক্ত পদ্ধতিতে নিয়ে যায়। NIST-ও এই কারণে বিকল্প দেওয়া আর সরে যাওয়ার পরিকল্পনা রাখার কথা বলে। বাংলাদেশের মতো দেশে বাটন ফোন আর এজেন্টভিত্তিক সেবার বাস্তবতা ভুলে গিয়ে শুধু passkey-র কথা বললে বহু মানুষ বাদ পড়বেন। তাই রূপান্তর হতে হবে ধাপে ধাপে, আর কে পিছিয়ে পড়ছেন সেদিকে চোখ রেখে।

মূল উপলব্ধি: নিরাপত্তার সিদ্ধান্ত “সেরা প্রযুক্তি” বাছা নয়, নির্দিষ্ট মানুষের জন্য ঝুঁকি আর নাগালের ভারসাম্য খোঁজা। দুর্বল পদ্ধতি রাখতে হলেও তার চারপাশে কী সুরক্ষা আছে, সেটিই আসল প্রশ্ন।

প্র ০২TOTP-তে server-কে secret রাখতেই হয়। এই “shared secret” নকশার দাম কী, আর passkey কীভাবে সমস্যাটি বদলে দেয়?

Symmetric নকশায় যাচাইকারী আর প্রমাণকারীর ক্ষমতা সমান। যে code যাচাই করতে পারে, সে code বানাতেও পারে। তাই TOTP-র server database আসলে একটি চাবির ঘর। Password-এর মতো hash করে এড়ানো যায় না, কারণ HMAC হিসাবের জন্য আসল secret লাগে।

২০১১ সালের ঘটনাটি এই আলোচনায় প্রায়ই আসে। সে বছরের মার্চে RSA জানায়, একটি জটিল হামলায় তাদের SecurID পণ্য-সংক্রান্ত তথ্য চুরি হয়েছে। ওই token-এ প্রতিটি যন্ত্রের একটি seed থাকে। চুরি হওয়া তথ্যে seed ছিল কি না, প্রতিষ্ঠানটি তখন স্পষ্ট করে বলেনি, আর গ্রাহকদের দুশ্চিন্তাও ছিল ঠিক এটি নিয়েই। অর্থাৎ সরবরাহকারী বা server-এর হাতে seed-এর ভান্ডার থাকলে সেটি নিজেই একটি মূল্যবান লক্ষ্য।

রক্ষকের করণীয় কয়েকটি:

  • Seed encrypt করে রাখা, key আলাদা KMS বা HSM-এ।
  • যাচাই একটি ছোট, আলাদা service-এ করা, যেখানে অল্প কিছু পথ দিয়ে পৌঁছানো যায়।
  • Seed কখনো log না করা, enrollment-এর পরে আর না দেখানো।
  • ফাঁস হলে সবার seed বদলানোর পরিকল্পনা আগেই রাখা।

Passkey সমস্যাটিকে অন্য জায়গায় সরিয়ে দেয়। Server শুধু public key রাখে, যা দিয়ে যাচাই হয়, স্বাক্ষর হয় না। Database পুরো ফাঁস হলেও কেউ login করতে পারে না। এটি পর্ব ১০-এর asymmetric ধারণার সবচেয়ে ব্যবহারিক লাভগুলোর একটি। তবে ঝুঁকি শূন্য হয় না। Database-এ লেখার ক্ষমতা থাকলে কেউ নিজের public key বসিয়ে দিতে পারে। তাই অখণ্ডতা রক্ষা আর audit log তখনও দরকার।

মূল উপলব্ধি: ভালো নকশা ক্ষমতাকে ভাগ করে। যে যাচাই করে, তার হাতে যদি প্রমাণ বানানোর ক্ষমতা না থাকে, তাহলে তার ফাঁস অনেক কম বিপজ্জনক।

প্র ০৩Security key থাকলেও কোন কোন পথে account ঝুঁকিতে পড়তে পারে?

২০২২ সালের Cloudflare প্রতিবেদন আর ২০১৮ সালে Google-এর ভাষ্য security key-র শক্তি দেখায়। Cloudflare জানায়, তিনজন কর্মী নকল পাতায় তথ্য দিলেও login হয়নি। তবে “phishing-প্রতিরোধী” মানে “হামলা-প্রতিরোধী” নয়। একটি সৎ তালিকা বানাই।

  • Session চুরি: Login শেষ হওয়ার পরে cookie চুরি হলে passkey-র আর ভূমিকা নেই। ক্ষতিকর software browser থেকে সেটি নিতে পারে। প্রতিকার হলো endpoint সুরক্ষা, ছোট session, আর পর্ব ১৭-এর আলোচনা।
  • আসল origin-এই কোড চলা: আসল সাইটে XSS থাকলে ক্ষতিকর script আসল origin থেকেই চলে। Origin binding তখন সাহায্য করে না, কারণ origin সত্যিই ঠিক। পর্ব ৪০ দেখুন।
  • Fallback: সাইটে SMS-এ নামার পথ খোলা থাকলে নকল পাতা সেদিকেই ঠেলে দিতে পারে।
  • Recovery আর helpdesk: ভালো কথায় ভুলিয়ে কর্মীকে দিয়ে নতুন passkey যোগ করানো যায়। পর্ব ৫২-তে এর প্রতিরক্ষা।
  • যন্ত্র দখল: খোলা ফোন হাতে পেলে অন্য কেউ স্থানীয় যাচাই পেরিয়ে যেতে পারে। Biometric আর PIN-এর মানই সেখানে সীমা।
  • Authorization-এর ভুল: কে কী করতে পারে, সেটি login-এর প্রশ্ন নয়। পর্ব ১৯ দেখুন।

তাই একজন ভালো প্রকৌশলী বলবেন না, “Passkey দিয়েছি, কাজ শেষ।” বলবেন, “Credential phishing-এর একটি পুরো শ্রেণি আমরা বন্ধ করেছি। এখন হামলাকারীর পরের সেরা পথ কী?” এই প্রশ্নটিই পর্ব ৪-এর threat modeling.

মূল উপলব্ধি: একটি শক্ত control হামলাকে শেষ করে না, সরিয়ে দেয়। Control বসানোর পরে হামলাকারীর সস্তা পথটি কোথায় গেল, সেটি খোঁজাই রক্ষকের পরের কাজ।

প্র ০৪একটি ব্যাংক তার সাধারণ গ্রাহকদের জন্য synced passkey, না device-bound passkey বেছে নেবে?

সহজ উত্তর হলো, “গ্রাহক কারা আর কোন কাজ” না জেনে সিদ্ধান্ত হয় না। দুই দিকের যুক্তি দেখি।

Device-bound-এর পক্ষে: Key একটি যন্ত্র থেকে বের হয় না। NIST AAL3-র জন্য key exportable না হওয়ার শর্ত রাখে। ব্যাংক জানে কোন যন্ত্রে key আছে।

Device-bound-এর বিপক্ষে: বাংলাদেশে ফোন হারানো, ভাঙা, বদলানো খুব সাধারণ ঘটনা। প্রতিবার গ্রাহক recovery-তে পড়বেন। Recovery যদি শাখায় যাওয়া বা কল সেন্টার হয়, তাহলে খরচ বাড়ে, আর দুর্বল হলে সেটিই আক্রমণের নতুন পথ। Key হারানোর ভয়ে মানুষ SMS-ই বেছে নিতে পারেন।

Synced-এর পক্ষে: নতুন ফোনে key নিজে থেকেই আসে, তাই recovery কমে। NIST Appendix B AAL2 পর্যন্ত এর অনুমতি দেয়, শর্ত হলো sync-এর সময় key encrypted থাকবে, আর sync account AAL2-সমতুল্য MFA দিয়ে রক্ষিত থাকবে।

Synced-এর বিপক্ষে: ব্যবহারকারীর cloud account দখল হলে key-র কাছে পৌঁছানো সহজ হতে পারে। NIST ধরে নিতে বলে, সাধারণ মানুষের synced key শেয়ার হতে পারে। ব্যাংকের নিয়ন্ত্রণের বাইরে একটি পক্ষ যুক্ত হয়।

বাস্তবসম্মত নকশা প্রায়ই স্তরভিত্তিক। সাধারণ login আর ছোট লেনদেনে synced passkey গ্রহণ করা হয়, কারণ phishing ঠেকানোর লাভটি একই। বড় লেনদেন, নতুন প্রাপক বা passkey যোগের মতো কাজে step-up আর ঝুঁকির সংকেত যোগ হয়। কর্পোরেট অ্যাকাউন্ট আর ব্যাংকের নিজের admin-দের জন্য থাকে device-bound key. BE/BS flag দিয়ে ব্যাংক বুঝতে পারে কোন ধরনের credential এল। Passkey সরানোর মান হিসেবে FIDO-র Credential Exchange Format প্রস্তাবিত মান হয়েছে, তবে protocol অংশটি যতদূর জানা যায় এখনও খসড়া পর্যায়ে, তাই এটি যাচাই করে নেবেন।

মূল উপলব্ধি: সবচেয়ে “শক্ত” পদ্ধতি সবসময় সবচেয়ে নিরাপদ ফল দেয় না। মানুষ যে পদ্ধতি বাস্তবে ধরে রাখতে পারেন আর যার recovery দুর্বল নয়, সেটিই আসল নিরাপত্তা দেয়।

প্র ০৫“Login শক্ত, recovery দুর্বল” — এই ফাঁদ এড়িয়ে একটি recovery ব্যবস্থা কীভাবে নকশা করবেন?

Recovery একটি অদ্ভুত নকশার সমস্যা। সংজ্ঞা অনুযায়ী এটি তখনই চলে, যখন স্বাভাবিক প্রমাণ নেই। তাই ব্যবস্থাটিকে কম প্রমাণে বেশি বিশ্বাস করতে হয়, আর সেটিই হামলাকারী খোঁজে। Authentication-এর নিরাপত্তা তার সবচেয়ে দুর্বল বিকল্প পথের সমান। এটি পর্ব ৩-এর complete mediation-এর আরেক রূপ: সব পথে সমান যাচাই চাই।

নকশার ক্রম এমন হতে পারে:

  • প্রয়োজন কমানো: শুরুতেই দ্বিতীয় authenticator নিতে উৎসাহ দিন। Synced passkey-ও recovery-র চাহিদা কমায়।
  • আগে থেকে প্রস্তুত পথ: NIST সংরক্ষিত recovery code-এ অন্তত ৬৪ bit চায়, hash করে রাখা আর ব্যবহারের পরে বাতিল করার কথা বলে।
  • ঝুঁকি অনুযায়ী প্রমাণ: NIST AAL2-র জন্য বলে ভিন্ন পদ্ধতিতে পাওয়া দুটি recovery code, অথবা recovery code আর একটি নিবন্ধিত single-factor authenticator, অথবা নতুন করে পরিচয় যাচাই।
  • Helpdesk-এর প্রক্রিয়া: লিখিত script, callback নিবন্ধিত নম্বরে, দ্বিতীয় ব্যক্তির অনুমোদন। কর্মী “না” বলতে পারবেন, আর সেজন্য তাঁকে দোষ দেওয়া হবে না।
  • জানানো: Recovery সবসময় notification পাঠায়, যা NIST-ও আবশ্যক করে। আসল মালিক অন্তত টের পান।
  • ক্ষতি সীমিত করা: Recovery-র পরে কিছু সময় বড় লেনদেন আর নতুন প্রাপক বন্ধ, অন্য session থেকে log out.
  • নজরদারি: Recovery-র পরে অল্প সময়ে নতুন passkey যোগ, তারপর বড় লেনদেন একটি সতর্কসংকেত।

গোপন প্রশ্ন (মায়ের নাম, প্রথম স্কুল) এড়িয়ে চলুন। এর উত্তর প্রায়ই সামাজিক মাধ্যমে পাওয়া যায়, আর পরিবর্তনও করা যায় না। Recovery নকশা পরীক্ষা করুন একটি অনুমোদিত মহড়ায়, নিজের দল দিয়ে, লিখিত অনুমতিতে। পর্ব ৬৬-এর tabletop মহড়ার মতো সাজানো যায়।

মূল উপলব্ধি: Recovery-কে মূল login-এর পরে ভাবা অংশ হিসেবে দেখলে সে-ই সবচেয়ে দুর্বল দরজা হয়। শুরুতেই “ফোন হারালে কী হবে?” প্রশ্নটি দিয়ে নকশা করুন।

অনুশীলন

হিসাব, পূর্বাভাস, নকশা-পর্যালোচনা আর নিজের account গুছিয়ে নেওয়া।

  1. হিসাব: একটি কাল্পনিক সেবায় ছয় অঙ্কের TOTP, window ±১. Rate limit নিয়ম হলো ১৫ মিনিটে ৫টি ব্যর্থ চেষ্টা, তারপর বিরতি, আর পরে আবার ৫টি। Account কখনো স্থায়ীভাবে বন্ধ হয় না। ৩০ দিনে সর্বোচ্চ কত অনুমান সম্ভব, আর অন্তত একবার সফল হওয়ার সম্ভাবনা কত? NIST-এর “১০০ ব্যর্থতায় বন্ধ” নিয়মের সঙ্গে তুলনা করুন।

    দিনে ১৫ মিনিটের ভাগ ৯৬টি। তাই দিনে ৯৬ × ৫ = ৪৮০ অনুমান। ৩০ দিনে ৪৮০ × ৩০ = ১৪,৪০০ অনুমান।

    p = 3 / 106, তাই P = 1 − (1 − 0.000003)14400 ≈ ৪.২৩%. আর ১০০ ব্যর্থতায় বন্ধ হলে P ≈ ০.০৩%. তফাত প্রায় ১৪০ গুণ।

    শিক্ষা: “মোট” সীমা আর “হার” সীমা এক নয়। শুধু হার সীমিত হলে সময় অনুমানকারীর পক্ষে কাজ করে। তাই সফল login না হওয়া পর্যন্ত ব্যর্থতার গণনা জমতে থাকা উচিত, আর ব্যর্থতার ধারা দেখলে ব্যবহারকারীকে জানানো ও সতর্কবার্তা তোলা দরকার।

  2. ফল অনুমান করুন: Time step ৩০ সেকেন্ড, window ±১, প্রতিটি ধাপের code আলাদা। শুরুতে lastStep = 100. Server যে ধাপের code পেলে তা গ্রহণ করে, সেটি নতুন lastStep হয়। ক্রমে চারটি অনুরোধ: (ক) t = 3035-এ ধাপ 100-র code (খ) t = 3040-এ ধাপ 102-র code (গ) t = 3065-এ ধাপ 101-র code (ঘ) t = 3100-এ ধাপ 101-র code. প্রতিটির ফল আর শেষের lastStep কী?
    • (ক) বর্তমান ধাপ ⌊3035 / 30⌋ = 101. ধাপ 100 window-র ভেতরে, কিন্তু 100 ≤ lastStep, তাই replay, বাতিল।
    • (খ) বর্তমান ধাপ 101. ধাপ 102 হলো +১, window-র ভেতরে আর lastStep-এর চেয়ে বড়। গ্রহণ, lastStep = 102.
    • (গ) বর্তমান ধাপ 102. ধাপ 101 window-র ভেতরে, কিন্তু 101 ≤ 102, তাই replay, বাতিল। Code-টি আগে ব্যবহৃত না হলেও পুরোনো ধাপ বলে বাতিল।
    • (ঘ) বর্তমান ধাপ 103. ধাপ 101 হলো −২, window-র বাইরে। Invalid, বাতিল।

    শেষে lastStep = 102.

  3. নকশা-সমালোচনা: একটি কাল্পনিক ফিনটেক অ্যাপের login এমন: passkey প্রধান পথ। নিচে একটি লিংক “Passkey কাজ করছে না? SMS code নিন।” SMS code দিয়ে login হলে নতুন passkey যোগ করা যায়, আর তখনই বড় লেনদেনও করা যায়। Call center ফোনে জন্মতারিখ শুনে নম্বর বদলে দেয়। এই নকশার সমস্যা আর উন্নতি লিখুন।
    • Fallback: Passkey-র phishing প্রতিরোধ বাস্তবে নেই, কারণ নকল পাতা “SMS code নিন” পথে ঠেলে দিতে পারে। নিরাপত্তা SMS-এর সমান।
    • Enrollment: দুর্বল পথ দিয়ে শক্ত পদ্ধতি যোগ করা যায়। অর্থাৎ SIM swap বা OTP relay-র পরে স্থায়ী প্রবেশ মেলে।
    • লেনদেন: দুর্বল login-এর পরেও সব ক্ষমতা। Step-up নেই।
    • Call center: জন্মতারিখ গোপন তথ্য নয়। নম্বর বদল account recovery-র সমান, তাই শক্ত পরিচয় যাচাই লাগবে।

    উন্নতি: SMS-এ ঢুকলে সীমিত ক্ষমতা, passkey যোগের আগে অপেক্ষার সময় আর notification, বড় লেনদেনে step-up, নম্বর বদলের পরে কিছুদিন সীমিত লেনদেন, call center-এ লিখিত প্রক্রিয়া আর দ্বিতীয় অনুমোদন। Passkey আছে এমন গ্রাহকের জন্য SMS বন্ধ রাখার বিকল্প দেওয়া।

  4. নিজের account গুছিয়ে নিন: নিজের সবচেয়ে গুরুত্বপূর্ণ তিনটি account (email, মোবাইল ব্যাংকিং বা ব্যাংক, পাসওয়ার্ড ম্যানেজার) বেছে নিন। প্রতিটির জন্য লিখুন: কোন MFA চালু আছে, দুর্বলতম বিকল্প পথ কোনটি, ফোন হারালে কীভাবে ফিরবেন। এটি শুধু নিজের account-এ করুন।

    একটি ভালো উত্তরে সাধারণত যা থাকে:

    • Email আগে, কারণ অন্য সব সেবার password reset সেখানে যায়। এটি আপনার recovery-র শিকড়।
    • সেবাটি দিলে passkey বা security key, না হলে TOTP. দুটি authenticator যোগ করা।
    • Backup code ছাপিয়ে আলাদা নিরাপদ জায়গায় রাখা। Screenshot নয়, গ্যালারির সঙ্গে sync হতে পারে।
    • SMS বিকল্পটি বন্ধ করা যায় কি না দেখা। অনেক ব্যাংকিং সেবায় তা সম্ভব নয়, তখন SIM আর ফোনের PIN শক্ত করা।
    • একবার নিয়ন্ত্রিতভাবে recovery পরীক্ষা করা। যা কখনো পরীক্ষা করেননি, তার ওপর ভরসা করবেন না।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমWebAuthn login-এর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. Server একটি নতুন random challenge পাঠায়
  2. Browser origin মিলিয়ে clientDataJSON তৈরি করে
  3. Authenticator RP ID দিয়ে credential খুঁজে ব্যবহারকারীকে যাচাই করে
  4. Authenticator private key দিয়ে স্বাক্ষর করে
  5. Server origin, challenge, rpIdHash আর signature যাচাই করে session দেয়

একজন কর্মী একটি নকল login পাতায় password আর ৬ অঙ্কের TOTP দিলেন, আর ঠিক তখনই কেউ সেগুলো আসল সাইটে ব্যবহার করল। TOTP এটি ঠেকাতে পারল না কেন?

  • HMAC-SHA-1 ভাঙা গেছে
  • OTP সাইটের নামের সঙ্গে বাঁধা নয়, তাই বৈধ সময়ের মধ্যে অন্য জায়গায় ব্যবহার করা যায়
  • Server-এর window খুব বড় ছিল
  • Server-এর seed অবশ্যই ফাঁস হয়েছে

RFC 6238-এ t = 1234567890, time step 30 সেকেন্ড হলে counter T কত?

  • 20576131
  • 41152264
  • 41152263
  • 1234567890

ছয় অঙ্কের TOTP, window ±১ (একসঙ্গে ৩টি code বৈধ), আর ১০০ ব্যর্থ চেষ্টায় authenticator বন্ধ হয়। অনুমান করে সফল হওয়ার সম্ভাবনা প্রায় কত?

  • ০.০১%
  • ৩%
  • ৩০%
  • ০.০৩%

Password hash করে রাখা হয়, কিন্তু TOTP seed সাধারণত encrypt করে রাখা হয়। কেন?

  • Code হিসাবের জন্য server-এর আসল seed লাগে
  • Seed এত ছোট যে hash করা যায় না
  • Seed গোপন তথ্য নয়
  • SHA-1 hash করার জন্য নিরাপদ নয়

Push login-এ number matching চালু করলে কোন সমস্যা সবচেয়ে বেশি কমে?

  • Real-time phishing relay
  • MFA fatigue থেকে অন্ধ অনুমোদন
  • SIM swap
  • Session cookie চুরি

NIST SP 800-63B-4 অনুযায়ী কোন বক্তব্যটি ঠিক?

  • TOTP phishing-প্রতিরোধী, কারণ code ৩০ সেকেন্ডে বদলায়
  • Syncable passkey AAL3-তে ব্যবহার করা যায়
  • AAL3-তে phishing-প্রতিরোধী authenticator আবশ্যক
  • SMS OTP সম্পূর্ণ নিষিদ্ধ

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. MFA চুরি হওয়া password-এর ক্ষতি কমায়, কিন্তু session চুরি, malware আর দুর্বল recovery থামায় না।
  2. TOTP = HMAC(secret, ⌊t/30⌋). শক্তি আসে rate limit, ছোট window আর replay সুরক্ষা থেকে, আর seed রাখতে হয় encrypted অবস্থায়।
  3. Number matching অন্ধ অনুমোদন ঠেকায়, কিন্তু হাতে টাইপ করা যেকোনো মান relay হতে পারে।
  4. Origin binding মানুষের চোখের কাজ browser আর স্বাক্ষরকে দেয়। তাই নকল সাইট passkey থেকে কিছু পায় না, আর server রাখে শুধু public key.
  5. Login-এর শক্তি তার সবচেয়ে দুর্বল fallback আর recovery পথের সমান। Rollout শেষ হয় দুর্বল পথ বন্ধ করে।

পরের পর্বে: Login সফল হলো। এবার server আপনাকে মনে রাখবে কীভাবে? পর্ব ১৭-তে থাকছে Session আর token: cookie, JWT আর নিরাপদ logout.

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান