ওভারভিউ
এখানে পাসকি প্রমাণীকরণের সাথে জড়িত মূল পদক্ষেপগুলির একটি উচ্চ-স্তরের ওভারভিউ রয়েছে:
- একটি পাসকি দিয়ে প্রমাণীকরণের জন্য প্রয়োজনীয় চ্যালেঞ্জ এবং অন্যান্য বিকল্পগুলি সংজ্ঞায়িত করুন। সেগুলি ক্লায়েন্টের কাছে পাঠান, যাতে আপনি সেগুলিকে আপনার পাসকি প্রমাণীকরণ কলে পাঠাতে পারেন ( ওয়েবে
navigator.credentials.get
)৷ ব্যবহারকারী পাসকি প্রমাণীকরণ নিশ্চিত করার পরে, পাসকি প্রমাণীকরণ কলটি সমাধান করা হয় এবং একটি শংসাপত্র প্রদান করে (PublicKeyCredential
)। শংসাপত্রে একটি প্রমাণীকরণ দাবি রয়েছে।
- প্রমাণীকরণ দাবী যাচাই করুন.
- প্রমাণীকরণ দাবি বৈধ হলে, ব্যবহারকারীকে প্রমাণীকরণ করুন।
নিম্নলিখিত বিভাগগুলি প্রতিটি ধাপের সুনির্দিষ্ট বিষয়গুলিতে ডুব দেয়।
চ্যালেঞ্জ তৈরি করুন
অনুশীলনে, একটি চ্যালেঞ্জ হল র্যান্ডম বাইটের একটি অ্যারে, যা একটি ArrayBuffer
অবজেক্ট হিসাবে উপস্থাপিত হয়।
// Example challenge, base64URL-encoded
weMLPOSx1VfSnMV6uPwDKbjGdKRMaUDGxeDEUTT5VN8
চ্যালেঞ্জটি তার উদ্দেশ্য পূরণ করে তা নিশ্চিত করতে, আপনাকে অবশ্যই:
- নিশ্চিত করুন যে একই চ্যালেঞ্জ একবারের বেশি ব্যবহার করা হয় না। প্রতিটি সাইন-ইন প্রচেষ্টায় একটি নতুন চ্যালেঞ্জ তৈরি করুন৷ প্রতিটি সাইন-ইন প্রচেষ্টার পরে চ্যালেঞ্জটি বাতিল করুন, তা সফল হোক বা ব্যর্থ হোক। একটি নির্দিষ্ট সময়ের পরে চ্যালেঞ্জটিও বাতিল করুন। একবারের বেশি প্রতিক্রিয়ায় একই চ্যালেঞ্জ গ্রহণ করবেন না।
- নিশ্চিত করুন চ্যালেঞ্জটি ক্রিপ্টোগ্রাফিকভাবে সুরক্ষিত । একটি চ্যালেঞ্জ অনুমান করা কার্যত অসম্ভব হওয়া উচিত । একটি ক্রিপ্টোগ্রাফিকভাবে সুরক্ষিত চ্যালেঞ্জ সার্ভার-সাইড তৈরি করতে, আপনার বিশ্বাস করা একটি FIDO সার্ভার-সাইড লাইব্রেরির উপর নির্ভর করা ভাল। আপনি যদি পরিবর্তে আপনার নিজের চ্যালেঞ্জ তৈরি করেন, আপনার টেক স্ট্যাকে উপলব্ধ অন্তর্নির্মিত ক্রিপ্টোগ্রাফিক কার্যকারিতা ব্যবহার করুন, বা ক্রিপ্টোগ্রাফিক ব্যবহারের ক্ষেত্রে ডিজাইন করা লাইব্রেরিগুলি সন্ধান করুন৷ উদাহরণের মধ্যে রয়েছে Node.js-এ iso-crypto , অথবা Python-এর গোপনীয়তা । স্পেসিফিকেশন অনুসারে, নিরাপদ বলে বিবেচনা করার জন্য চ্যালেঞ্জটি কমপক্ষে 16 বাইট দীর্ঘ হতে হবে।
একবার আপনি একটি চ্যালেঞ্জ তৈরি করলে, পরে যাচাই করতে ব্যবহারকারীর সেশনে এটি সংরক্ষণ করুন।
শংসাপত্রের অনুরোধের বিকল্পগুলি তৈরি করুন
একটি publicKeyCredentialRequestOptions
অবজেক্ট হিসাবে শংসাপত্রের অনুরোধের বিকল্পগুলি তৈরি করুন৷
এটি করতে, আপনার FIDO সার্ভার-সাইড লাইব্রেরির উপর নির্ভর করুন। এটি সাধারণত একটি ইউটিলিটি ফাংশন অফার করবে যা আপনার জন্য এই বিকল্পগুলি তৈরি করতে পারে। SimpleWebAuthn অফার করে, উদাহরণস্বরূপ, generateAuthenticationOptions
.
publicKeyCredentialRequestOptions
পাসকি প্রমাণীকরণের জন্য প্রয়োজনীয় সমস্ত তথ্য থাকা উচিত। আপনার FIDO সার্ভার-সাইড লাইব্রেরির ফাংশনে এই তথ্যটি পাঠান যা publicKeyCredentialRequestOptions
অবজেক্ট তৈরির জন্য দায়ী।
কিছু publicKeyCredentialRequestOptions
' ক্ষেত্র ধ্রুবক হতে পারে। অন্যদের গতিশীলভাবে সার্ভারে সংজ্ঞায়িত করা উচিত:
-
rpId
: আপনি কোন RP আইডির সাথে শংসাপত্র যুক্ত হবে বলে আশা করেন, উদাহরণস্বরূপexample.com
। প্রমাণীকরণ তখনই সফল হবে যদি আপনি এখানে যে RP ID প্রদান করেন সেটি শংসাপত্রের সাথে যুক্ত RP ID-এর সাথে মিলে যায়। RP আইডি পপুলেট করতে, শংসাপত্র নিবন্ধনের সময় আপনিpublicKeyCredentialCreationOptions
এ যে RP আইডি সেট করেছেন সেই মানটি ব্যবহার করুন। -
challenge
: ডেটার একটি অংশ যা পাসকি প্রদানকারী প্রমাণীকরণের অনুরোধের সময় ব্যবহারকারীর কাছে পাসকি ধারণ করে তা প্রমাণ করতে স্বাক্ষর করবে। চ্যালেঞ্জ তৈরি করুন -এ বিবরণ পর্যালোচনা করুন। -
allowCredentials
: এই প্রমাণীকরণের জন্য গ্রহণযোগ্য শংসাপত্রের একটি অ্যারে। ব্যবহারকারীকে ব্রাউজার দ্বারা দেখানো একটি তালিকা থেকে একটি উপলব্ধ পাসকি নির্বাচন করতে দেওয়ার জন্য একটি খালি অ্যারে পাস করুন৷ বিশদ বিবরণের জন্য RP সার্ভার এবং আবিষ্কারযোগ্য শংসাপত্রগুলি থেকে একটি চ্যালেঞ্জ নিয়ে আসা পর্যালোচনা করুন। -
userVerification
: ডিভাইসের স্ক্রিন লক ব্যবহার করে ব্যবহারকারীর যাচাইকরণ "প্রয়োজনীয়", "পছন্দের" বা "নিরুৎসাহিত" কিনা তা নির্দেশ করে। রিভিউ RP সার্ভার থেকে একটি চ্যালেঞ্জ আনুন । -
timeout
: ব্যবহারকারী কতক্ষণ (মিলিসেকেন্ডে) প্রমাণীকরণ সম্পূর্ণ করতে নিতে পারে। এটি যুক্তিসঙ্গতভাবে উদার হওয়া উচিত এবংchallenge
জীবনকালের চেয়ে ছোট হওয়া উচিত। প্রস্তাবিত ডিফল্ট মান হল 5 মিনিট , কিন্তু আপনি এটি বাড়াতে পারেন — 10 মিনিট পর্যন্ত, যা এখনও প্রস্তাবিত সীমার মধ্যে রয়েছে৷ আপনি যদি ব্যবহারকারীদের হাইব্রিড ওয়ার্কফ্লো ব্যবহার করার আশা করেন তবে দীর্ঘ সময়সীমা অর্থপূর্ণ হয়, যা সাধারণত একটু বেশি সময় নেয়। অপারেশন সময় শেষ হলে, একটিNotAllowedError
নিক্ষেপ করা হবে।
একবার আপনি publicKeyCredentialRequestOptions
তৈরি করলে, এটি ক্লায়েন্টের কাছে পাঠান।
উদাহরণ কোড: শংসাপত্রের অনুরোধের বিকল্পগুলি তৈরি করুন
আমরা আমাদের উদাহরণে SimpleWebAuthn লাইব্রেরি ব্যবহার করছি। এখানে, আমরা ক্রেডেনশিয়াল রিকোয়েস্ট অপশন তৈরি করার কাজটি এর generateAuthenticationOptions
ফাংশনে হস্তান্তর করি।
import {
generateRegistrationOptions,
verifyRegistrationResponse,
generateAuthenticationOptions,
verifyAuthenticationResponse
} from '@simplewebauthn/server';
router.post('/signinRequest', csrfCheck, async (req, res) => {
// Ensure you nest calls in try/catch blocks.
// If something fails, throw an error with a descriptive error message.
// Return that message with an appropriate error code to the client.
try {
// Use the generateAuthenticationOptions function from SimpleWebAuthn
const options = await generateAuthenticationOptions({
rpID: process.env.HOSTNAME,
allowCredentials: [],
});
// Save the challenge in the user session
req.session.challenge = options.challenge;
return res.json(options);
} catch (e) {
console.error(e);
return res.status(400).json({ error: e.message });
}
});
ব্যবহারকারী যাচাই করুন এবং সাইন ইন করুন
যখন navigator.credentials.get
ক্লায়েন্টে সফলভাবে সমাধান করে, তখন এটি একটি PublicKeyCredential
অবজেক্ট ফেরত দেয়।
response
হল একটি AuthenticatorAssertionResponse
। এটি RP-এ একটি পাসকি দিয়ে চেষ্টা এবং প্রমাণীকরণের জন্য যা প্রয়োজন তা তৈরি করার জন্য ক্লায়েন্টের নির্দেশে পাসকি প্রদানকারীর প্রতিক্রিয়া উপস্থাপন করে। এতে রয়েছে:
-
response.authenticatorData
এবংresponse.clientDataJSON
, যেমন পাসকি রেজিস্ট্রেশন ধাপে। -
response.signature
যা এই মানগুলির উপর একটি স্বাক্ষর ধারণ করে।
সার্ভারে PublicKeyCredential
অবজেক্ট পাঠান।
সার্ভারে, নিম্নলিখিতগুলি করুন:
- দাবীটি যাচাই করতে এবং ব্যবহারকারীকে প্রমাণীকরণ করতে আপনার প্রয়োজনীয় তথ্য সংগ্রহ করুন:
- আপনি প্রমাণীকরণ বিকল্পগুলি তৈরি করার সময় সেশনে সঞ্চিত প্রত্যাশিত চ্যালেঞ্জটি পান৷
- প্রত্যাশিত মূল এবং আরপি আইডি পান।
- ব্যবহারকারী কে আপনার ডাটাবেসে খুঁজুন. আবিষ্কারযোগ্য শংসাপত্রের ক্ষেত্রে, আপনি জানেন না যে ব্যবহারকারী কে একটি প্রমাণীকরণ অনুরোধ করছে। খুঁজে বের করতে, আপনার দুটি বিকল্প আছে:
- বিকল্প 1:
PublicKeyCredential
অবজেক্টেresponse.userHandle
ব্যবহার করুন। ব্যবহারকারীর টেবিলে,userHandle
সাথে মেলে এমনpasskey_user_id
সন্ধান করুন। - বিকল্প 2:
PublicKeyCredential
অবজেক্টে উপস্থিত শংসাপত্রid
ব্যবহার করুন। পাবলিক কী শংসাপত্রের সারণীতে,PublicKeyCredential
অবজেক্টে উপস্থিত শংসাপত্রid
সাথে মেলে এমন শংসাপত্রid
সন্ধান করুন৷ তারপর আপনার ব্যবহারকারীদের টেবিলে বিদেশী কীpasskey_user_id
ব্যবহার করে সংশ্লিষ্ট ব্যবহারকারীর সন্ধান করুন।
- বিকল্প 1:
- আপনার ডাটাবেসে সর্বজনীন কী শংসাপত্রের তথ্য খুঁজুন যা আপনি প্রাপ্ত প্রমাণীকরণ দাবীর সাথে মেলে। এটি করতে, পাবলিক কী শংসাপত্রের টেবিলে,
PublicKeyCredential
অবজেক্টে উপস্থিত শংসাপত্রid
সাথে মেলে এমন শংসাপত্রid
সন্ধান করুন৷
প্রমাণীকরণ দাবী যাচাই করুন. এই যাচাইকরণের ধাপটি আপনার FIDO সার্ভার-সাইড লাইব্রেরিতে হস্তান্তর করুন, যা সাধারণত এই উদ্দেশ্যে একটি ইউটিলিটি ফাংশন অফার করবে। SimpleWebAuthn অফার করে, উদাহরণস্বরূপ,
verifyAuthenticationResponse
। পরিশিষ্টে হুডের নিচে কী ঘটছে তা জানুন: প্রমাণীকরণ প্রতিক্রিয়া যাচাইকরণ ।রিপ্লে আক্রমণ প্রতিরোধ করতে, যাচাইকরণ সফল হোক বা না হোক চ্যালেঞ্জটি মুছুন ।
ব্যবহারকারী সাইন ইন করুন. যাচাইকরণ সফল হলে, ব্যবহারকারীকে সাইন-ইন করা হিসেবে চিহ্নিত করতে সেশনের তথ্য আপডেট করুন। আপনি ক্লায়েন্টকে একটি
user
বস্তু ফেরত দিতে চাইতে পারেন, যাতে ফ্রন্টএন্ড নতুন সাইন-ইন করা ব্যবহারকারীর সাথে সম্পর্কিত তথ্য ব্যবহার করতে পারে।
উদাহরণ কোড: ব্যবহারকারী যাচাই করুন এবং সাইন ইন করুন
আমরা আমাদের উদাহরণে SimpleWebAuthn লাইব্রেরি ব্যবহার করছি। এখানে, আমরা প্রমাণীকরণ প্রতিক্রিয়ার যাচাইকরণ তার verifyAuthenticationResponse
ফাংশনে হস্তান্তর করি।
import {
generateRegistrationOptions,
verifyRegistrationResponse,
generateAuthenticationOptions,
verifyAuthenticationResponse
} from '@simplewebauthn/server';
import { isoBase64URL } from '@simplewebauthn/server/helpers';
router.post('/signinResponse', csrfCheck, async (req, res) => {
const response = req.body;
const expectedChallenge = req.session.challenge;
const expectedOrigin = getOrigin(req.get('User-Agent'));
const expectedRPID = process.env.HOSTNAME;
// Ensure you nest verification function calls in try/catch blocks.
// If something fails, throw an error with a descriptive error message.
// Return that message with an appropriate error code to the client.
try {
// Find the credential stored to the database by the credential ID
const cred = Credentials.findById(response.id);
if (!cred) {
throw new Error('Credential not found.');
}
// Find the user - Here alternatively we could look up the user directly
// in the Users table via userHandle
const user = Users.findByPasskeyUserId(cred.passkey_user_id);
if (!user) {
throw new Error('User not found.');
}
// Base64URL decode some values
const authenticator = {
credentialPublicKey: isoBase64URL.toBuffer(cred.publicKey),
credentialID: isoBase64URL.toBuffer(cred.id),
transports: cred.transports,
};
// Verify the credential
const { verified, authenticationInfo } = await verifyAuthenticationResponse({
response,
expectedChallenge,
expectedOrigin,
expectedRPID,
authenticator,
requireUserVerification: false,
});
if (!verified) {
throw new Error('User verification failed.');
}
// Kill the challenge for this session.
delete req.session.challenge;
req.session.username = user.username;
req.session['signed-in'] = 'yes';
return res.json(user);
} catch (e) {
delete req.session.challenge;
console.error(e);
return res.status(400).json({ error: e.message });
}
});
পরিশিষ্ট: প্রমাণীকরণ প্রতিক্রিয়া যাচাইকরণ
প্রমাণীকরণ প্রতিক্রিয়া যাচাই করার জন্য নিম্নলিখিত চেকগুলি রয়েছে:
- নিশ্চিত করুন যে RP ID আপনার সাইটের সাথে মেলে।
- নিশ্চিত করুন যে অনুরোধের উৎস আপনার সাইটের সাইন-ইন মূলের সাথে মেলে। অ্যান্ড্রয়েড অ্যাপ্লিকেশানগুলির জন্য, যাচাই মূল পর্যালোচনা করুন৷
- ডিভাইসটি আপনার দেওয়া চ্যালেঞ্জ প্রদান করতে সক্ষম হয়েছে কিনা তা পরীক্ষা করুন।
- যাচাই করুন যে প্রমাণীকরণের সময়, ব্যবহারকারী আপনার RP হিসাবে বাধ্যতামূলক প্রয়োজনীয়তাগুলি অনুসরণ করেছেন। আপনার যদি ব্যবহারকারীর যাচাইকরণের প্রয়োজন হয়, নিশ্চিত করুন যে
authenticatorData
ডেটাতেuv
(ব্যবহারকারী যাচাইকৃত) পতাকাটিtrue
।authenticatorData
ডেটাতেup
(ব্যবহারকারীর উপস্থিত) পতাকাটিtrue
কিনা তা পরীক্ষা করুন, যেহেতু পাসকিগুলির জন্য সর্বদা ব্যবহারকারীর উপস্থিতি প্রয়োজন । - স্বাক্ষর যাচাই করুন। স্বাক্ষর যাচাই করতে, আপনার প্রয়োজন:
- স্বাক্ষর, যা স্বাক্ষরিত চ্যালেঞ্জ:
response.signature
- সর্বজনীন কী, সহ স্বাক্ষর যাচাই করতে।
- মূল স্বাক্ষরিত ডেটা। এটি সেই ডেটা যার স্বাক্ষর যাচাই করতে হবে।
- ক্রিপ্টোগ্রাফিক অ্যালগরিদম যা স্বাক্ষর তৈরি করতে ব্যবহৃত হয়েছিল।
- স্বাক্ষর, যা স্বাক্ষরিত চ্যালেঞ্জ:
এই ধাপগুলি সম্পর্কে আরও জানতে, verifyAuthenticationResponse
জন্য SimpleWebAuthn-এর সোর্স কোড দেখুন বা স্পেসিফিকেশনে যাচাইকরণের সম্পূর্ণ তালিকায় ডুব দিন।