ایجاد: ۹:۰۴ ۱۳۹۲/۱۲/۲۵
ویرایش: ۲۱:۲۰ ۱۳۹۳/۱۲/۱
»
یک برنامه نویس هر چقدر هم نکات امنیتی را در برنامه نویسی و سمت سرور لحاظ کند، روی امنیت سمت کلاینت (کاربر) تسلط و کنترل کاملی ندارد. چون براوزر دسترسیهای محدودی به او میدهد.
یکی از ضعفهای سمت کاربر که میتواند موجب لو رفتن پسورد کاربران (مدیران) سایت شود، برنامههای کیلاگر است که ممکن است (بلکه به احتمال زیاد!) روی دستگاه کاربر نصب شده باشد.
key logger ها، همه کلیدهای فشرده شده روی کیبورد را ذخیره و به سازنده آن کیلاگر ارسال میکنند.
روشهایی برای مقابله با این خطر وجود دارد که استفاده از کیبورد مجازی یکی از روشهای آن است. هم اکنون در صفحه پرداخت اینترنتی بسیاری از بانکها هم میتوانید آن را مشاهده کنید.
اما جاسوسهای کیلاگر نوین، همزمان با کلیک کاربر، از صفحه عکس میگیرند! و با این کار امنیت کیبوردهای مجازی هم خنثی میشود!
بهترین راه مقابله با کیلاگرها، پسورد یکبار مصرف است که از روشی غیر از کامپیوتر فعلی کاربر، به دستش برسد. در این حالت، کیلاگری که پسوردها را ذخیره و به سازندهاش ارسال میکند، بیاثر میشود چون پسورد ذخیره شده توسط کیلاگر، فقط یکبار معتبر بوده است نه بیشتر!
پسورد یکبار مصرف تولید شده، نباید توسط کامپیوتر کاربر (یا حتی وسیله دیگری با همان خط اینترنت) به دست کاربر برسد زیرا در اینصورت؛ علاوه بر کاربر، برنامه جاسوس نیز میتواند به آن دست یابد.
پسوردهای یکبار مصرف معمولا به 3 روش به دست کاربر میرسد؛
-
ارسال پیامک (SMS) به موبایل کاربر
شماره موبایل کاربر پس از ثبت در سیستم و سنجش اعتبار آن، یکی از راههای متداول برای ارسال رمز یکبار مصرف است.
-
تولید و نمایش/پرینت تعدادی رمز یکبار مصرف
میتوان به تعداد لازم (مثلا 20 تا) رمز یکبار مصرف، برای یک دوره زمانی (مثلا یک ماه) تولید کرد تا کاربر آن را یادداشت/پرینت کند و هر بار یکی از آنها را استفاده کند.
-
استفاده از یک سخت افزار مستقل از کامپیوتر کاربر و شبکه اینترنت وی
دقت کنید که در روش اول و سوم، رمز تولید شده برای مدت زمانی کوتاهی (مثلا سی ثانیه) اعتبار دارد.
خب بسیاری از سایتها ممکن است امکان ارسال پیامک را نداشته باشند یا به دلیل تعداد زیاد کاربران و در نتیجه هزینه زیاد، استفاده از این روش را مقرون به صرفه ندانند لذا روش اول تنها برای سایتهایی مناسب است که تعداد کاربران معدودی داشته باشد یا اینکه سایت مربوطه از کاربرانش بسیار بیشتر از هزینه یک پیامک، پول دربیاورد! (مانند گوگل)
روش دوم (تولید و پرینت/نمایش تعداد مشخصی پسورد یکبارمصرف به کاربر) نیز حداقل دو اشکال دارد. یکی اینکه کاربر لازم است پسوردها را روی کامپیوتری امن تولید کند (مگر کاربران محدود باشند و رمزهای یکبار مصرف به صورت چاپ شده به آنها داده شود) و اشکال دوم هم این است که باید قبل از نیاز، تمهیداتش انجام و تولید شود یعنی کسی که به یکباره مسافرت میرود یا در جایی گرفتار میشود و تنها یک کامپیوتر و اینترنت نامطمئن در دسترس دارد، نمیتواند به فکر تولید رمز یکبار مصرف بیفتد!
اما روش سوم که به نظر بهتر میرسد، این است که یک سخت افزار مستقل از کامپیوتر کاربر که نیازی هم به شبکه و اینترنت ندارد، پسورد یکبارمصرف را به دست کاربر برساند!
شرکتهای بزرگ تجاری، یک وسیله کوچک و کاملا مستقل برای این امر تهیه و در اختیار مشتریانشان قرار میدهند. مثلا در ایران بانکهای ملی و صادرات و ... وسیلهای به اسم «دستگاه رمزیاب» برای تولید رمز یکبارمصرف در اختیار مشتریان قرار میدهند اما مدیران سایتها که نمیخواهند چنان هزینهای بکنند، چه راهی برای تولید یکبار مصرف دارند؟
پاسخ ساده است. موبایل!
این روزها تقریبا همه مردم موبایل دارند. ولو یک موبایل ساده که html/javascript را میفهمد.
البته اگر موبایل (یا تبلت)، دارای سیستمعامل اندرویدی یا اپلی باشد، برنامهها و امکانات بیشتری (مانند اسکن بارکد QR) نیز دارند و کار را برای کاربران سادهتر میکند.
پسوردهای یکبار مصرف (One Time Passwords) که اختصارا OTP گفته میشود، به چند روش میتواند تولید شود که شایعترین آنها، روش «مبتنی بر زمان» یا Time-base است که TOTP گفته میشود.
در روش TOTP یک پسورد حسب زمان تولید میشود و مدت محدودی (مثلا 30 ثانیه) هم معتبر است لذا لازم است ساعت موبایل کاربر بیش از آن مقدار محدود (مثلا 30 ثانیه) با ساعت جهانی اختلاف نداشته باشد و الا پسورد تولید شده توسط موبایل، به هیچوجه موثر نخواهد بود. البته لازم به ذکر است که موبایلهای امروزی، ساعتشان را با کمک اینترنت همواره دقیق نگهمیدارند و معمولا نگرانی از این بابت نداریم.
یک رمز مبتنی بر زمان، میتواند بر اساس 1 یا 2 کلیدواژه تولید شود؛
رمز مبتنی بر زمان، به این صورت تولید میشود که کلیدواژه(ها) به همراه زمان هش میشود و آن هش به صورت یک پسورد موقت ارائه میشود. البته برای سادگی کار، به جای خود زمان، زمان یونیکسی (Unix Timestamp) را بر مدت زمان اعتبار (مثلا 30 ثانیه) تقسیم میکنند تا عددی به دست بیاید که در مدت زمان اعتبار (مثلا 30 ثانیه) ثابت میماند.
به عنوان مثال، یک برنامه میتواند با 2 کلیدواژه، پسورد مبتنی بر زمانی را برای مدت 30 ثانیه، اینگونه تولید کند:
<?php
$timeDial = floor( time() / 30 );
$tempPassword = md5($key1.$key2.$timeDial);
همانطور که میبینید، پسورد فوق، وابسته به کلیدواژههای key1, key2 و متغیر timeDial است که timeDial نیز هر 30 ثانیه عوض میشود پس خروجی کد فوق (که یک پسورد موقت مبتنی بر زمان و کلیدواژه است)، هر 30 ثانیه یکبار عوض میشود.
همانطور که میبینید، پسورد موقت تولید شده، خروجی یک تابع هش است. یعنی یک رشتهی حداقل 32 کاراکتری هگزای مشتمل بر کاراکترهای 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 و a, b, c, d, e, f
خب طبیعی است که تایپ چنین رشته طولانی برای کاربر ملالآور است! در اینجا 2 کار میتوان انجام داد تا کاربر راحت باشد؛ یکی برش خروجی و نمایش بخشی از آن (مثلا 6 کاراکتر اول) و راه حل دوم هم تبدیل آن هش به یک عدد. توضیح آنکه خروجی تابع هش، مانند یک عدد در مبنای 16 است که با تقسیم آن بر یک عدد دیگر، میتوان طول آن را به مقدار دلخواه کم کرد. مثلا اگر ما یک عدد حداکثر 200 رقمی داشته باشیم، با تقسیم آن بر یک عدد 193 رقمی ثابت، میتوانیم طول آن را به 8 رقم کاهش دهیم.
کلیدهای تولید یک رمز OTP چگونه به برنامه مولد رمز داده میشود؟
همانطور که گفته شد، OTP میتواند با 1 کلیدواژه (که در اصطلاح secret key گفته میشود) تولید شود. این کلیدواژه فقط یکبار و به صورت دستی (یا توسط بارکد QR) لازم است در برنامه موبایلی مولد OTP وارد میشود و تمام.
اما در روش 2 کلیدواژهای، هربار لازم است یک کلیدواژه دیگر (PIN) که یک عدد یا رشته رندوم است، توسط صفحه احراز هویت (مثلا صفحه login.php)، تولید و به کاربر نمایش داده شود تا کاربر آن کلیدواژه را در برنامه تحت موبایلش درج کند و رمزیکبار مصرف بر اساس زمان+secretKey+PIN را دریافت کند و در صفحه Login درج کند. درست مانند تصویر روبرو.
نکته: OTP گاهی جایگزین پسورد اصلی میشود (مانند آنچه در تصویر میبینید) و گاهی هم مکمل پسورد اصلی میشود یعنی علاوه بر پسورد اصلی، یک رمز یکبارمصرف هم لازم است.
چگونه پسوردها یکبار مصرف میشوند؟
از نظر محدودیت زمانی، پسورد تولید شده، محدود به استفاده در زمان خاصی است. اما برای یکبار مصرف بودن آن چطور؟ روش ساده برای اطمینان از یکبار مصرف بودن پسورد ارسالی، این است که پسوردهای یکبارمصرفی را که به سرور ارسال میشود و صحت آن تائید میشود، به همراه زمان، در دیتابیس ذخیره کنیم و در آن زمان معین (مثلا سی ثانیه) اجازه استفاده دوباره از آن پسورد یکبارمصرف را ندهیم...
برنامههایی برای تولید پسورد یکبارمصرف
برنامههای زیادی وجود دارد که حسب نوع سیستمعامل موبایل کاربر میتواند استفاده شود. کافی است در بین نرمافزارهای مربوط به آن سیستمعامل، کلمه totp را جستجو کنید. مثلا اگر از سیستمعامل شایع Android استفاده میکنید، میتوانید از نرمافزار عمومی Google Authenticator که توسط گوگل (و نه فقط برای استفاده در سایت گوگل) ارائه شده است، در سایت خودتان نیز استفاده کنید. این اپلیکیشن اندرویدی، مبتنی بر یک کلید 16 کاراکتری در مبنای 32 است که میتواند به صورت دستی یا از طریق اسکن بارکد QR وارد برنامه شود و بر اساس هش «زمان+کلید» به روش SHA1، خروجی بر روی عددی 6 رقمی نگاشته (map) میشود. برنامههای مشابه دیگری نیز وجود دارد که کاربرد مشابهی دارند.
به دلیل ضعف عملکرد آن (6رقمی بودن خروجی و همچنین استفاده از هش sha1) لازم است این روش، مکمل پسورد اصلی باشد نه جایگزین آن. اگر دنبال استفاده از OTP به عنوان جایگزین پسورد اصلی هستید، استفاده از برنامه FreeOTP از شرکت معظم RedHat ، گزینه مناسبتری خواهد بود چرا که با کمک این برنامه اندرویدی، میتوانید بر اساس یک کلیدواژه با طول دلخواه (نه مثل Google Authenticator محدود به 16 کاراکتر) خروجی 8 رقمی داشته باشید که بر اساس هش بسیار قوی SHA-512 تولید شده است که حمله به آن (لااقل تا زمان ما) ممکن نبوده است.
برای لمس بیشتر این موضوع، من یک نمونه درست کردم و آن در اینجا قرار دادم. کافی است با برنامه Google Authenticator (نسخه اندرویدی یا اپلی) آن را اسکن کنید تا برنامه به شما پسوردی 6 رقمی نمایش دهد و همانطور که میبینید، این پسورد 6 رقمی با آنچه در نسخه آزمایشی نوشته، یکسان است. (البته ممکن است چندثانیه یا حتی یکی دو دقیقه بین ساعت موبایل شما و ساعت جهانی اختلاف باشد که برای این موضوع برنامه سمت سرور میتواند پسورد کمی قبل و بعد را هم با پسوردی که وارد کردید، مقایسه کند و اگر OTP وارد شده برابر یکی از پسوردهای زمان نزدیک به زمان فعلی بود، پس از سی ثانیه مجددا از شما OTP را بپرسد تا مطمئن شود که علت دقیق نبودن OTP شما، اختلاف زمانی ساعت شماست...)
پروژه 2FLogin یک پروژه ساده (شامل فایل اندروید+PHP) است که هرچند جدید نیست اما برای آشنایی بیشتر با این مبحث مفید است.
پسوردهای OTP را چگونه در سرور چک کنیم؟
روش تصدیق پسوردهای یکبار مصرف در سرور، اینگونه است که شما در سرور نیز پسورد یکبارمصرف مختص آن زمان را تولید میکنید و با پسورد ارسال شده توسط کاربر مقایسه میکنید. اگر یکسان بود که تصدیق میشود.
هرکدام از گزینههای بالا (برنامههای مبتنی بر تک کلید) را که انتخاب کنید، برای احراز هویت آن پسورد یکبارمصرف در سمت سرور، میتوانید با کمک کتابخانههای استانداردی همچون کتابخانهی رایگان و ساده OTPHP یا کتابخانه پیشرفته multiOTP که به زبان PHP نوشته شدهاند، پسوردهای تولیدشده توسط اپلیکیشنهای فوق را چک کنید.
اگر از برنامههای مبتنی بر 2 کلید استفاده میکنید، باز هم لازم است در سمت سرور هم از همان مکانیسم تولید پسورد در موبایل کاربر استفاده کنید و پسورد تولید شده مختص آن زمان را تولید و با پسورد ارسالشده توسط کاربر مقایسه کنید.
مثلا چنانچه از پروژه Mobile-OTP (یا M-OTP) استفاده میکنید، برای سمت کاربر میتوانید از برنامههای مختلفی (مثل برنامه ساده DroidOTP یا برنامه پیشرفتهتر Mobile OTP یا سایر برنامههای معرفی شده در صفحه این پروژه که فقط مختص اندروید نیست) استفاده کنید و برای سمت سرور هم از یک کد بسیار ساده شبیه کد زیر که به زبان PHP نوشته شده است:
<?php
function checkOTP($pin, $otp, $key)
{
$period = 6; // 6 * 10 = 60 sec
$time = substr(time(), 0, -1);
for($i = $time - $period; $i <= $time + $period; $i++)
if($otp==substr(md5($i.$key.$pin),0,6))
return true;
return false;
}
var_dump(checkOTP('123789', '985dfa', 'alireza123456789'));
محاسن و معایب پسورد یکبار مصرف
محاسن: همانطور که گفته شد، پسورد یکبار مصرف، بهترین روش برای مقابله با keyLogger ها است چرا که پسورد دزدیده شده توسط key logger ارزشی ندارد و فقط یکبار قابل استفاده بوده که استفاده شده است.
همچنین اگر پسورد یکبارمصرف به عنوان جایگزین پسورد اصلی استفاده شود، یک حسن دیگر هم دارد و آن اینکه کاربر ناچار نیست رمزهای خود را حفظ کند. توضیح آنکه بسیاری از کاربران برای سادگی کارشان، یک رمز ثابت و ساده را برای اکثر حسابهایشان به کار میبرند که این امر میتواند اطلاعات حساس آنها را به مخاطره بیندازد. اما در روش اشارهشده، کاربر کلیدواژه مختص خود را یکبار در موبایل خود وارد میکند و از آن به بعد، رمز یکبار مصرف تولید شده را تایپ میکند و نیاز نیست به ذهنش فشار بیاورد که پسوردش در این سایت چه بوده است!
معایب: مانند سایر روشهای احراز هویت، به این روش نیز برخی اشکالات وارد شده که که با تمهیداتی (که توسط برنامهنویس و کاربر باید انجام شود) میتوان بخشی از آنها را رفع کرد که فعلا مجال صحبت درباره آن نیست...
پسورد یکبار مصرف برای یک سایت وردپرسی
آنچه در بالا گفته شد، بیشتر برای برنامهنویسان بود. اما با توجه به اهمیت و کارآیی رمز یکبار مصرف برای امنیت ورود به بخش مدیریت سایتها، پلاگینهایی نیز برای سیستمهای مدیریت محتوا تهیه شده است.
مثلا اگر شما از WordPress استفاده میکنید (که یکی از پرطرفدارترین CMS های دنیاست و 40 درصد سایتهای دنیا بر آن بنا نهاده شده است)، میتوانید از پلاگین Google Authenticator و ... برای این منظور استفاده کنید و بخش Login وردپرس خود را امنتر کنید.
یادداشتهای مرتبط
- API چیست؟
- ارتقاء امنیت وردپرس
- آشنایی با دو قابلیت جدید مرورگرها: WebRTC و ضبط صدا و تصویر!
- لیست مواردی که برای امنیت برنامه PHP لازم است چک شود
- امنیت در انگولر جی اس
- رمزنگاری، هش، عملیات بیتی
- ثبت نام و ورود به بخش کاربری با حساب گوگل، فیس بوک، توئیتر و ...
- انواع روش های شناسایی و احراز هویت کاربران یک صفحه وب
- پیشگیری از حملات جعل درخواست بین سایتی
- حملات ضدامنیتی XSS یا تزریق کد
- نکاتی در مورد نسخه جدید PHP 5.5
- تنظیم اچ تی ام ال پیوریفایر
- نکات و ترفندهایی برای قالب دهی به نمای چاپ صفحات وب
- انواع راه های تولید کد QR با پی اچ پی و جاوا اسکریپت