صد رازِ نهان

یک شمع، با روشن کردن شمعی دیگر چیزی از دست نمی‌دهد!

۵ مطلب با کلمه‌ی کلیدی «استانداردهای سیم کارت» ثبت شده است

جاواکارت مقدماتی/9- Hello World در جاواکارت

قسمت قبلی: برنامه نویسی جاواکارت در محیط Eclipse
پس از آشنا شدن با مراحل ساخت یک پروژه ی ساده در دو IDE مشهورِ Eclipse و Netbeans، اینک نوبت به آن می‌رسد که دست به کُد شویم! :) طبق روال جا افتاده در دنیای برنامه نویسی، کار خود را با برنامه‌ی Hello World در جاواکارت آغاز می‌کنیم. همه‌ی کاری که این اپلت انجام می‌دهد این است که در پاسخ به هر دستوری که به کارت ارسال می‌شود، عبارت "Hello World" را بازگردانی می‌کند.

سلام دنیا!
کار خود را، با افزودن خطوطی به برنامه‌ی قالبی ای که Eclipse یا Netbeans در مراحل قبل در اختیار ما قرار دادند آغاز می‌کنیم. با فرض این که شما در مراحل ایجاد پروژه، اسم پروژه را "HelloWorld" و اسم پکیج را "helloWorldPackage" انتخاب کرده باشید، پس از حذف Commentهای اتوماتیکی که IDE اضافه می‌کند، تکه کدی، مشابه کد زیر خواهید داشت:

همانطور که در تصویر بالا مشاهده می کنید، برنامه به سه قسمت کلی تقسیم شده است. خط اول، نام Package می‌باشد. قبلا نیز اشاره کرده بودیم که حتما به Package اپلت خود،یک نام اختصاص دهید و هیچگاه فیلد آن را خالی مگذارید، چرا که خالی گذاشتن این فیلد، خصوصا در محیط Eclipse، هنگام Compile برنامه، خطاهایی عجیبی نمایان می‌کند! پکیج در واقع، فایلی است که درون آن اپلت قرار گرفته است، و بسته به نوع کارت، پس از نصب اپلت می‌توان نام پکیج را نیز در کارت مشاهده کرد.
قسمت دوم که شامل یک مجموعه خطوط است که با کلمه‌ی import شروع شده اند، قسمت افزودن Libraryهای ضروری به برنامه است. با توجه به کارکردی که یک برنامه‌ی جاواکارت قرار است داشته باشد، اوراکل، کتابخانه‌های مختلفی تهیه کرده است و همراه JCDK در اختیار برنامه‌نویس قرار داده است. تابع های این کتابخانه‌ها(ماژول ها)، با توجه به ارتباط و کاربردشان به دسته‌های مختلف تقسیم شده اند. برنامه نویس هنگامی که نیاز به استفاده از یک تابع دارد، ابتدا باید ماژولی که این تابع در آن قرار دارد را import کند. البته IDE به صورت خودکار، در صورتی که شما تابعی استفاده کنید که ماژول آن import نشده است، با نمایش یک خطا شما را آگاه می‌سازد و پیشنهاد import کردن آن ماژول را می‌دهد. اصلی ترین ماژول ها و تابع ها که به صورت پیش فرض توسط IDE در آغاز ساخت پروژه، import  می شوند، ماژول های زیرمجموعه ی javacard.framework می‎باشند. 
و اما قسمت سوم و قسمت اساسی اپلت، همان "کلاس" آن است. 
همانند زبان جاوا، در زبان جاواکارت نیز، هر اپلت متشکل از یک کلاس است که توابع ما (Methods/Functions) داخل این کلاس قرار می‌گیرند. یکی از نکات حائز اهمیتی که اپلت‌های جاواکارت را از برنامه‌های نوشته شده به زبان جاوا متمایز می‌کند این است که، همه‌ی اپلت‌های جاواکارت باید از کلاس Applet مشتق بشوند (به عبارت دیگر همگی باید فرزند کلاس Applet باشند- لطفا این کلاس را با نام برنامه های جاواکارت اشتباه نگیرید!). کلاس Applet، یکی از کلاس های موجود در کتابخانه‌ی javacard.frameword است که ما در ابتدای برنامه import کردیم. این عمل مشتق شدن(به ارث بردن) با عبارت extends Applet در خط شماره‌ی 5 برنامه انجام شده است.

در زبان جاوا/جاواکارت و سایر زبان‌های برنامه نویسی شیء گرا، وقتی یک کلاس از کلاس دیگری مشتق می‌شود، دو اتفاق می‌افتد:
  1. به کلاس فرزند(کلاس که به ارث می‌برد=کلاسی که قبل از کلمه‌ی extends می‌آید)، فیلدها (Fields = Variables = متغیرها) و متدهای کلاس والد اضافه‌ می‌شوند (بجز آنچه که در کلاس والد از نوع Private تعریف شده است) و برنامه نویس می‌تواند از آن‌ها استفاده کند.
  2. برنامه نویس مجبور به پیاده سازی متدهای Abstract کلاس والد می‌شود.(متدی که در کلاس والد تنها prototype آن[= خط تعریف] نوشته شده است و پیاده سازی آن به کلاس های به ارث برنده واگذار شده است).

در مورد کلاس Applet نیز به همین صورت است. با مشتق شدن اپلت ما از این کلاس، مجبور می‌شویم متد های Abstract آن را پیاده سازی کنیم. تنها متد Abstract این کلاس، متد process است(خط 16). پیش از آن که به توصیف عملکرد این کلاس بپردازیم تعریف کلّی دو متد پیشین، یعنی install و helloWorld و ذکر یک مقدمه خالی از فایده نیست. 

فرض کنیم که اپلت خود را تکمیل کرده ایم و قصد داریم روی کارت از آن استفاده کنیم. برای این منظور، نیاز به انجام دو مرحله داریم:
  1. بارگذاری پکیج و اپلت درون آن (بله، یک یا چند اپلت، درون یک پکیج قرار می‌گیرند و روی کارت بارگذاری می‌شوند) روی کارت. 
  2. نصب اپلت بارگذاری شده.
از آنجا که به انجام دو مرحله‌ی بالا در اصطلاح Install کردن اپلت گفته می‌شود، برای تمییز آن‌ها از یکدیگر، از دو عبارت Install for Load و Install for Install استفاده می‌شود. 
نکته‌ی بعدی این است که، ما می‌توانیم چند بار اپلت خود را با نام‌های مختلف(یعنی AIDهای مختلف) روی کارت نصب کنیم (مشابه این که چند بار Microsoft Office را با نام‌های مختلف در آدرس های مختلف رایانه نصب کنیم). برای این منظور، تنها یکبار عملیات Install for Load را انجام می‎‌دهیم و پس از آن عملیات Install for Install را به تعداد دلخواه تکرار می‌کنیم. 
اتفاقی که در علمیات Install for Load می‌افتد این است که فایل cap. از داخل رایانه به داخل حافظه‌ی کارت منتقل شده و آنجا Extract می‌شود. سپس AID پکیج و اپلت درون آن در جدول محتویات کارت قرار ثبت می‌شود.
و اتفاقی که در عملیات Install for Install رخ می‌دهد این است که متد install داخل اپلت (خط شماره‌ی 8) توسط Java Card Runtime Environment (با کمی اغماض می‌توانید به جای JCRE بخوانید Card Manager) فراخوانی می‌شود. نکته‌ی حائز اهمیت در مورد این متد این است که، برای هر اپلت نصب شده این متد یکبار و فقط یکبار، آن هم فقط و فقط توسط JCRE فراخوانی می‌شود. در واقع هیچ موجودیت(اپلت) دیگری روی کارت، دسترسی کافی برای فراخوانی آن را ندارد. 
در مورد پارامترهایی که جلوی متد install به عنوان ورودی این تابع معرفی شده اند، به این توصیف بسنده می‌کنیم که این پارامترها، همان AID اپلت در حال نصب می‌باشند. یعنی، وقتی قرار است اپلت بارگذاری شده را چند بار نصب کنیم، این متد را با ورودی های مختلف که همان AIDهای مختلف هستند، فراخوانی می‌کنیم. در آینده‌ی این کار را به صورت عملی خواهیم دید.

متد بعدی که نام آن باید با نام اپلت  یکی باشد، اصطلاحا Instructor یا سازنده نامیده می‌شود. کلیه‌ی برنامه‌های نوشته شده به زبان جاوا/جاواکارت نیازمند وجود این متدهای Instructor می‌باشند. متد register که درون این متد فراخوانی شده است، وظیفه‌ی ثبت AID اپلت در Registry Table کارت را دارد. (جدولی که لیست AIDهای نصب شده روی کارت را در بر دارد).

و در نهایت، نوبت به سومین متد، یعنی متد process است. تقریبا، همه‌ی آنچه ما با آن کار داریم این متد است. اما چرا؟
پاسخ:
پس از آن که اپلت ما با موفقیت هر دو مرحله‌ی Install for Load و Install for Install را پشت سر گذاشت، AID مربوط به آن، درون جدول رجیستری JCRE ثبت می‌شود. حال برای ارتباط با این اپلت نصب شده ما به این صورت عمل می‌کنیم که ابتداءََ با یک دستور(دستور SELECT)، به Card Manager اطلاع می‌دهیم که قصد ارتباط به فلان اپلت را داریم. Card Manager پس از این که وجود آن اپلت را بررسی کرد، با یک جواب مشخص، امکان ارتباط یا عدم امکان ارتباط را به ما گزارش می‌دهد. [این دستورها و این پاسخ‌ها، همانطور که پیش‌تر گفته ایم، APDU Command و  APDU Response نامیده می‌شوند و متشکل از یک سری عدد هگزادسیمال هستند].
در صورتی که جواب Card Manager به ما، حاکی از وجود امکان ارتباط با اپلت مورد نظرمان بود، شروع به ارسال دستورات دلخواهمان به کارت می‌کنیم. چیزی که در پس این ارتباط رخ می‌دهد این است که:
  1. Card Manager این دستورات را از ما دریافت می‌کند و داخل یک بافر به نام APDU Buffer قرار می‌دهد.
  2. بررسی می‌کند که آیا این دستور، دستور  SELECT اپلت دیگری نباشد.
  3. بافر را به عنوان پارامتر، به متد process اپلتی که انتخاب شده است ارسال می‌کند و منتظر دریافت پاسخ از وی می‌ماند.
  4. اپلت ما، پس از خواندن دستور دریافت شده درون بافر، پردازش های خود را انجام داده و پاسخ خود را مجدد در APDU Buffer قرار می‌دهد و آن را به Card Manager باز می‌گرداند.
  5. Card Manager پاسخ دریافت کرده از متد process را به ما باز پس می‌دهد. 
  6. بازگشت به مرحله‌ی 1
همانطور که مشاهده می‌کنید، ارتباط ما با اپلت نصب شده روی کارت، همواره با یک واسطه‌ی Card Manager است. ارتباط با یک اپلت، تا زمانی برقرار است که یا دستور SELECT دیگری ارسال کنیم یا این که کارت را از کارتخوان خارج کنیم. در صورتی که در مرحله‌ی 2، کارتخوان متوجه دستور SELECT شود، به جای رفتن به مرحله‌ی 3، اپلت فعلی را از انتخاب خارج می‌کند و در جدول رجیستری، به دنبال اپلت جدید می‌گردد و ...
بنابرین، کاربرد متد process نیز مشخص شد. همچنین عبارت قرمز شده در مرحله‌ی 3 بدین معناست که با ارسال هر دستور به کارت، باید انتظار یک پاسخ -هر چند کوتاه- از وی داشت و نمی‌توان چند دستور ارسال کرد و یکباره پاسخ گرفت. (چیزی مانند ارتباط یک به یک). نکته‌ی آخر این که، کارت نمی‌تواند آغازگر ارتباط باشد، بلکه تمام وقت، به عنوان Slave در یک ارتباط Master-Slave منتظر دریافت دستور است. 

و اما برنامه‌ی HelloWorld!
تا اینجای کار، نسبت به اتفاقاتی که حین ارتباط با اپلت رخ می‌دهد آشنا شدیم و اینک نوبت آن است که به کد قالبی ارائه شده توسط IDE خطوطی اضافه کنیم که در پاسخ به دستورات ارسالی ما عبارت "Hello World" را بازگردانی کند. طبق توضیحات بالا، می‌دانیم قسمت عمده ای از آنچه که باید دستخوش تغییر یا افزودن شود، تابع process است. 
ساده ترین حالت برنامه‌ی ما به صورت زیر خواهد بود:

برای آشنایی با توابعی که اضافه کرده ایم، می‌توانید به Java Card API Specification (یک سند pdf داخل JCDK) مراجعه کنید. اما به صورت اجمالی، در خطوط 15 و 16 یک آرایه از نوع بایت به نام  HELLO_WORLD تعریف کردیم و حروفی که می‌خواهیم در پاسخ به دستورات دریافتی به کاربر ارسال شود را در آن قرار دادیم. در خط 17، از تابع getbuffer روی شیء apdu استفاده کردیم تا بتوانیم به بافر APDU دست پیدا کنیم. این تابع، در واقع یک آرایه‌ی بایتی از APDU Buffer باز می‌گرداند، بنابراین با این خط ما متغیر buffer را به APDU Buffer ارجاع دادیم. 
در خط 18 با استفاده از تابع arrayCopyNonAtomic محتویات متغیر HELLO_WORLD را درون متغیر buffer کپی کردیم(که منجر به تغییر APDU Buffer می‌شود) و در آخرین خط برنامه، با استفاده از تابع setOutgoingAndSend بافر APDU را که حاوی پاسخ است، به Card Manager بازگرداندیم که به کاربر بیرون کارت بازگرداند. 

هرچند برنامه‌ی فوق به صورت صحیح به فایل cap. تبدیل می‌شود و به صورت صحیح هم بارگذاری و اجرا می‌شود، اما دارای نقاط ضعفی است که باید حتما رفع شوند. در قسمت بعدی با رفع این نقاط ضعف و اجرای اپلت نهایی در محیط Simulator آشنا خواهیم شد.

قسمت بعدی: استفاده از Simulator های جاواکارت (به زودی!)

شهر خالی‌ست ز عشّاق، مگر کز طرفی
دستی از غیب برون آید و کاری بکند ...
#حافظ_دوست_داشتنی
۱۶ آذر ۹۴ ، ۲۳:۰۱ ۷ نظر موافقین ۱ مخالفین ۰
ابراهیم قاسمی

جاواکارت مقدماتی/8-برنامه نویسی جاواکارت در Eclipse

قسمت قبلی: برنامه نویسی جاواکارت در Netbeans

در قسمت قبل دیدیم که نسخه‌های جدید محیط برنامه نویسی Netbeans، به صورت پیشفرض، Pluginها و APIهای مورد نیاز برای برنامه نویسی جاواکارت را در خود دارند. متاسفانه در مورد محیط برنامه نویسی Eclipse اینگونه نیست (نویسنده از نسخه‌ی جدید این نرم افزار اطلاع ندارد). بنابراین نیاز است که برنامه نویس خودش Plugin و APIهای مورد نیاز را به آن بیفزاید.


سوال: IDE چیست؟ Plugin چیست؟ API چیست؟

پاسخ: IDE یا Integrated Development Environment یا محیط برنامه نویسی در واقع نرم افزارهایی مانند Netbeans، Eclipse یا Visual Studio هستند که فضایی را برای برنامه نویس فراهم می‌آوردند که برنامه‌های خود را به صورت راحت تر بنویسد و Compile/Interpret کند. 

API یا Application Programming Interface یا رابط برنامه نویسی نرم افزار، در واقع مجموعه ای از واسط/رابط ها بین برنامه ای که قرار است نوشته شود با کتابخانه‌های آن زبان یا سیستم عامل هستند. یکی از قابلیت‌هایی که IDE دارد این است که هنگام نوشتن برنامه و استفاده از این رابط های برنامه نویسی در کد برنامه، به صورت اتوماتیک چک می‌کند که آیا چنین رابطی وجود دارد یا خیر، و اگر موجود نبود، به برنامه نویس خطای استفاده از APIهای اشتباه می‌دهد و یا به وی کمک می‌کند آن را اصلاح کند. (بنابراین باید APIهای لازم را به محیط برنامه نویسی معرفی/اضافه کنیم).

و نهایتا Plugin مجموعه ای فایل است که برای یک نرم افزار مانند IDE نوشته شده اند که به آن قابلیتی اضافه کنند. 

به صورت روشن تر، وقتی ما JCDK را از سایت Oracle دانلود می‌کنیم، همه‌ی APIها و ابزارهای مورد نیاز برای نوشتن و ساخت یک اپلت در آن مجموعه وجود دارد. یعنی می‌توانیم بدون استفاده از هیچگونه IDE ای، اپلت خود را بنویسیم و فایل cap آن را تولید کنیم! منتهی باید با Notepad یا ابزاری مشابه آن، و یک مجموعه ابزارهای خط فرمانی دست و پنجه نرم کنیم، و هیچ گونه هشداری به ما در مورد نوشتن یک اسم API اشتباه یا خطاهای مانند آن به ما داده نمی شود، و تنها در مراحل پایانی، هنگام Compile/Interpret به واسطه ی اجرا نشدن موفق فرایند، متوجه وجود یک خطا در برنامه می‌شویم. کاری که IDE با Plugin هایش برای ما انجام می‌دهد، مکانیزه کردن کل این فرایندها و مخفی کردن ابزارهای خط فرمانی و مراحل آن ها، در پس چند کلیک ساده است. 


Eclipse:

خب، برای شروع، ابتدا Eclipse و سپس Java Card Development Kit 2.2.2 و پلاگین Eclipse-JCDE را دانلود می‌کنیم. 

نکته‌ی مهم اول: Eclipse و Java Development Kit و Java Card Development Kit 2.2.2 و Windows چهار مورد باید یا 32 بیتی باشند یا 64 بیتی. تفاوت یکی از این موارد با موارد دیگر موجب ناسازگاری مجموعه می‌شود و عدم کارکرد صحیح می‌شود.

نکته‌ی مهم دوم: همانطور که پیش‌تر گفته بودیم، پلاگین Eclipse-JCDE تنها برای JCDK2.2.2 نوشته شده است. بنابراین شما باید این نسخه از JCDK را دانلود کنید. (با ترفندی می‌توان از نسخه های پایین تر نیز استفاده کرد؛ لیکن، برای اجرای آن ترفندها، همچنان به نسخه‌ی 2.2.2 نیز نیاز است).

اما بعد؛ پس از دانلود موارد بالا:

  1.  ابتدا Java Development Kit را نصب کنید. پس از آن نرم افزار وارد پوشه‌ی Eclipse شوید(این نرم افزار به صورت Portable می‌باشد، یعنی نیاز به نصب ندارد و نهایتا تنها کاری که شما باید در مورد فایل دانلود شده‌ی آن بکنید، Extract کردن آن در یک دایرکتوری است).
  2. داخل پوشه‌ی Eclipse یک فولدر به نام plugins وجود دارد، محتویات Eclipse-JCDE (پلاگین دانلود شده) را در این فولدر قرار دهید.
  3. JCDK را در یک فولدر Extract کنید. وارد مسیر Extract شوید. داخل این دایرکتوری، چهار فایل فشرده می‌بینید. هر چهار مورد را مجدد Extract کنید (فایل اصلی java_card_kit-2_2_2-rr-bin-windows-do.zip است).
  4. حال نرم افزار Eclipse را باز کنید و از منوی Java Card (که به واسطه ی پلاگین دانلود شده به Eclipse اضافه شده است)، گزینه‌ی Preferences را انتخاب کنید. سپس روی Browse کلید کرده و مسیر پوشه ی  java_card_kit-2_2_2-rr-bin-windows-do را به آن بدهید و روی OK کلیک کنید. 
بعد از انجام مراحل بالا، محیط برنامه نویسی Eclipse برای ساخت پروژه های جاواکارت آماده است. برای ایجاد یک پروژه‌ی جاواکارت به این ترتیب عمل می‌کنیم:

1- File > New > Other

2- Java Card > Java Card Project - Next

3- Assigning a name to your project and then click on Finish.
 بعد از کلیک کردن روی دکمه‌ی Finish در منوی سمت راست Eclipse پوشه‌ای با نامی که شما در مرحله‌ی 3 به آن اختصاص دادید ظاهر می‌شود. این پوشه، پوشه‌ی خالی پروژه‌ی شماست:

4- File > New > Other > Java Card Applet
برای افزودن یک اپلت خام(:دی!) به پوشه‌ی پروژه، دو مسیر وجود دارد. راه نخست این که در حالی که پوشه‌ی پروژه انتخاب شده است، مجددا مراحل 1 و 2 را انجام دهیم، با این تفاوت که در مرحله‌ی 2، به جای Java Card Project،  گزینه‌ی Java Card Applet را انتخاب کنیم. مسیر دوم هم به این صورت است که به جای انتخاب کردن پوشه‌ی پروژه و رفتن به File > New، مستقیما روی خود پوشه‌ی پروژه کلید راست کنید و New و ... را پیش بروید. به هر حال از هر دو مسیر، پس از انتخاب Java Card Applet و کلیک روی Next، پنجره ی زیر ظاهر خواهد شد:

5- Assigning Package Name, Applet Name and Applet AID:

در مورد پنجره‌ی فوق چند نکته وجود دارد:
1- بنا بر رسم برنامه نویسی، اسم Package را با حرف کوچک و اسم Applet را با نام بزرگ شروع می‌کنند.
2- چنانچه Package Name را خالی بگذارید، Eclipse به شما هشداری نمی‌دهد، و حتی با کلیک کردن روی Finish، اپلت خام مورد نظر به پروژه اضافه می‌شود (که نام Package آن Default Package شده است)؛ اما، به هنگام ساخت فایل cap. خطایی دریافت می‌کنید که به هیچ وجه از متن آن مشخص نمی‌شود ایراد کجاست! بنابرین برای روبرو نشدن با خطا، حتما به Package یک نام اختصاص دهید.  
3- در این پنجره، تنها AID اپلت از برنامه نویس خواسته می‌شود و AID توسط IDE یک مقدار پیش‌فرض دریافت می‌کنید که در پنجره‌ی بعدی قابل تغییر است.

پس از کلیک کردن روی Finish پنجره ی نهایی که همان محیط برنامه نویسی جاواکارت است مجددا ظاهر می‌شود:

خطایی که مشاهده می‌کنید با پاک کردن override@ از متن برنامه حذف می‌شود. منوهایی که در کادر آبی مشاهده می‌کنید مواردی هستند که به کمک Plugin دانلود شده به Eclipse اضافه شده اند. JCWDE و CREF شبیه سازهای (Simulator) جاواکارت هستند که Oracle آن ها را در بسته‌ی Java Card Development Kit ارائه می‌دهد تا برنامه نویس بتواند بدون نیاز به یک کارت فیزیکی واقعی، برنامه‌ی خود را خطایابی کند. 

نهایتا پس از رفع خطا و ایجاد تغییرات مناسب در برنامه نوبت به ساخت فایل cap. می رسد. برای این کار یا از منوی Java Card در کادر آبی، یا با کلید راست کردن روی نام Package و رفتن به زیر منوی Java Card Tools، گزینه‌ی Convert را انتخاب می‌کنیم تا فایل cap ساخته شود:

6- Assigning Package AID and Generating CAP file:

از آنجا که در مراحل قبلی به Package برنامه AID اختصاص ندادیم، به صورت اتوماتیک یک پنجره باز می‌شود که از ما AID پکیج را می‌گیرد (چنانچه پیش از Convert از Set Package AID استفاده می‌کردیم، دیگر این پنجره ظاهر نمی‌شد). پس از اختصاص Package AID و کلیک روی OK، به احتمال خیلی زیاد، با خطای زیر مواجه خواهید شد:

علت این خطا، تنظیم بودن Compiler جاوا (بله جاوا، نه جاواکارت) در Eclipse روی نسخه‌هایی بالاتر از 1.3 است، برای ساخت فایل‌های cap جاواکارت نسخه‌ی 2.2.2 و قبل تر، کامپایلر جاوا حتما باید روی نسخه‌ی 1.3 (شاید 1.4 هم جوابگو باشد) تنظیم شود. برای تغییر آن، از منوی  Windows بالای پنجره‌ی Eclipse، گزینه‌ی Preferences را انتخاب کنید و سپس در پنجره‌ی باز شده مانند زیر عمل کنید:

حال، مجددا مرحله‌ی 6 را تکرار کنید تا فایل cap به صورت موفق آمیز ساخته شود:

همانطور که مشاهده می‌کنید در کادر سمت چپ، فایل cap ظاهر شده است. شما می‌توانید با کلیک راست کردن روی آن و انتخاب copy، آن را به هر کجای هارد انتقال دهید. همچنین می‌توانید با انتخاب properties، مسیر فعلی آن را مشاهده کنید.


آنچه پنهان در میان سینه باشد، عشق نیست
عاشقان با رسم رسوایی به میدان می‌روند
#عارفه_نصیری

۲۷ آبان ۹۴ ، ۲۳:۲۸ ۱ نظر موافقین ۰ مخالفین ۰
ابراهیم قاسمی

جاواکارت مقدماتی/7-برنامه نویسی جاواکارت در Netbeans

قسمت قبلی: نسخه‌های جاواکارت و اصطلاحات

در قسمت های پیشین با ساختار کلّی جاواکارت و مفاهیم ابتدایی ضروری آن آشنا شدیم و دانستیم که برای آغاز به نوشتن یک اپلت و تبدیل آن به فایل cap. (فایلی که روی کارت بارگذاری و نصب می‌شود) ابتدا به یک IDE (محیط برنامه نویسی)، یک مجموعه API (واسط‌ های از پیش نوشته شده‌ی JCDK , JDK)، یک ابزار برای بارگذاری و نصب اپلت و نهایتا یک ابزار برای ارتباط با آن نیاز داریم. در این قسمت مراحل نوشتن اپلت و تولید فایل cap. را در محیط Netbeans بررسی می‌کنیم.


Netbeans:

طبق آنچه پیش تر گفته شد، برنامه نویسی برای جاواکارت در محیط Netbeans، برای مواقعی مناسب از که کارت مورد نظر ما از نسخه ی جاواکارت 3.0.1 یا بالاتر پشتیبانی کند. البته لازم به ذکر است که به سبب Backward Compatible بودن استانداردهای جاواکارت، نوشتن اپلت هایی برای کارت های از ورژن پایین تر نیز در محیط Netbeans امکان پذیر است و حتی می‌توان از آنها فایل cap. تولید کرد و در Simulatorهای این IDE آن‌ها را بررسی کرد، لیکن، ورژن فایل نهایی 3.0.1 خواهد بود و قابلیت بارگذاری روی کارت پایین تر را نخواهد داشت. 

و اما روند نوشتن و تولید اپلت:

پس از اجرای Netbeans، از منوی File گزینه‌ی New Project را انتخاب می‌کتیم تا پنجره ی زیر ظاهر شود:

طبق تصویر بالا از سمت چپ گروه Java Card (چنانچه این گزینه را ندارید، باید نسخه‌ی جدیدتری از Netbeans را دریافت کنید یا پلاگین های مربوطه را دانلود و نصب کنید) و از سمت راست نوع پروژه را Classic Applet Project (جهت آشنایی به قبلی آموزش مراجعه کنید) انتخاب می‌کنیم و روی Next کلیک می‌کنیم تا پنجره‌ی زیر ظاهر شود:

در این پنجره و پنجره ی بعدی نام پروژه (نام کلاس اپلت)، نام پکیج اپلت، AID پکیج و AID اپلت را مشخص می‌کنیم. رسم بر این است که نام Package با حروف کوچک و نام Class با حروف بزرگ آغاز شود. همانطور که مشاهده می‌کنید Netbeans به صورت تصادفی یک AID شش بایتی به اپلت اختصاص داده است. فرمت این AID به صورت زیر است:
//aid/<First mandatory 5 bytes>/<Up to 11 bytes optional bytes>
به منظور راحت بودن در به خاطر سپردن AID می‌توانید مقدار دیگری مانند 010203040506 جایگزین آن کنید و پس از آن با کلیک مجدد روی Next به پنجره‌ی اختصاص AID به پکیج اپلت هدایت می‌شوید که فرمت آن به همان صورت AID مربوط به اپلت است. لازم به ذکر نیست که AID پکیج و اپلت باید با هم حداقل در یک "بیت" تفاوت داشته باشند. به صورت معنایی، اختصاص 5 بایت اول یکسان به AID اپلت و پکیج منطقی تر از متفاوت بودن آن‌ها است.
نکته: در میانه‌ی پنجره‌ی فوق دو گزینه‌ی Platforms و Cards به ترتیب نسخه‌های جاواکارت نصب شده روی Netbeans و نوع جاواکارتی که Simulator از آن استفاده می‌کند را مشاهده می‌کنیم. با احتمال بالایی، برای هرکدام تنها همین گزینه‌های مشخص شده را خواهید داشت، بنابرین در مورد آن‌ها بعدا صحبت خواهیم کرد.
پنجره‌ی نهایی که با اختصاص Package AID و کلیک روی Finish به صفحه‌ی نوشتن کد منتقل می‌شویم:

پس از کلیک روی دکمه‌ی Finish، نرم افزار Netbeans به صورت اتوماتیک سورس-کدِ ساده‌ترین اپلتِ ممکن را در اختیار شما قرار می‌دهد تا با ایجاد تغییر و توسعه‌ی آن، به صورت ساده تر اپلت مورد نظر خود را تولید کنید [سورس کد تولید شده توسط Netbeans تنها چهارچوب کلی است و هیچ فعالیتی انجام نمی‌دهد]. در مورد ساختار این سورس-کد و نحوه‌ی توسعه‌ی آن در پست های بعدی توضیحاتی داده خواهد شد، اما انتظار می‌رود خواننده خودش با مراجعه به سند Java Card API Specification دانش لازم را کسب کند.

پس از ایجاد تغییرات لازم، با استفاده از ابزارهای مشخص شده که معادل هر کدام از آنها در تَب  Run وجود دارد پروژه ی نوشته شده را Build می‌کنیم و در صورتی که قصد استفاده از Simulator را داشته باشیم با کلید روی مثلث سبز رنگ اپلت را اجرا می‌کنیم.

همانگونه که در تصویر بالا مشاهده می‌کنید، پس از کلید روی Build (چکش)، IDE با پیام BUILD SUCCESSFUL ما را از ساخت موفقیت آمیز فایل cap. آگاه می‌کند. چنانچه در کد برنامه خطایی وجود داشته باشد، عملیات Build با شکست مواجه می‌شود، ولی ساخت موفقیت آمیز فایل cap. نه به معنای این است که اپلت روی کارت به درستی کار خواهد کرد و نه حتی به معنای این است که اپلت روی کارت باگذاری و نصب خواهد شد! (در آینده با مثال هایی از هر دو مورد روبرو خواهیم شد).
قابل ذکر است که فایل cap. تولید شده، درون دایرکتوری ای با مسیر زیر قرار می‌گیرد:
Documents\NetBeansProjects\<YourProjectName>\dist\*.cap


آسمانی‌تر از آنی که کنارت باشم
حفظ کن فاصله را تا به تو عادت نکنم ...
#صنم_نافع
۱۸ آبان ۹۴ ، ۲۰:۴۸ ۰ نظر موافقین ۰ مخالفین ۰
ابراهیم قاسمی

جاواکارت-مقدماتی/3-احراز هویت


بخش احراز هویت و امنیت:

خب، گفتیم داخل کارت از زمان ساخت کارت یه اپلیکیشن به اسم Card Manager وجود داره که کار های مدیریتی کارت به عهده ی اونه. اما یه سوال پیش میاد، آیا هر کسی میتونه روی کارت یه اپلت نصب کنه یا حذف کنه؟ جوابش مشخصه و مسلما منفیه. 
حالا سوال بعدی اینه که کارت به کی جواب میده؟
جواب: همون لحظه ای که Card Manager داخل کارت نصب میشه، سه تا کلید رمزنگاری هم همراهش داخل کارت ذخیره میشه که یه مقدار پیشفرضی دارند و کسی که کارت رو میخره، با داشتن اونها میتونه این دستورات رو به کارت بده و کلید ها رو هم عوض کنه. 

خب، اول ببینیم احراز هویت کلا به چه صورت هایی میتونه باشه و بعد بگیم کارت از چه روشی استفاده میکنه:

احراز هویت:
  1. یک طرفه یا One Point Authentication
  2. دو طرفه یا Mutual Authentication
با یه مثال هر دو رو توضیح میدم. فرض کن من باید یه دستوری رو به شما بدم که اجراش کنی و فقط هم باید به شما بدم و نباید به هیچ کس دیگه ای بگم، شما هم باید یه دستور از من بگیری و اجرا کنی و نباید از هیچ کس دیگه ای دستور بگیری.
روش یک طرفه به این صورته که شما یه رمز به من دادی و من هم یه رمز به شما دادم، بعد من میام پیشت رمز رو میپرسم اگه درست گفتی رمزت رو با دستور بهت میگم و شما اگه منم رمز رو درست گفتم میری اجرا میکنی. خب ایرادش چیه؟ :) (سو سیمپل! خودت پیدا کن)
روش دوم اینه که من و شما از قبل یه رمزی و یه الگوریتمی رو با هم به اشتراک گذاشتیم (همون کلید[های] امنیتی پیش فرض که داخل کارخونه نوشته شده و بعد توسط کاربر قابل عوض شدنه). وقتی به هم میرسیم، من یه عدد تصادفی میدم به شما، شما هم یه عدد تصادفی میدی به من. هر دو با اون الگوریتم و اون کلیدهای پیشفرض عدد رندوم طرف مقابل رو رمز میکنیم و بهش پس میدیم. بعد هر کدوممون عدد رندوم خودمون رو هم با اون کلید و الگورتیم رمز کردیم به صورت داخلی. نتیجه ای که خودمون بهش رسیدیم رو با نتیجه ای که طرف مقابل بهمون داده مقایسه میکنیم، اگه با هم برابر بودند، نتیجه میگیریم که طرف مقابلمون کلید رو داره و بنابرین کسی هست که باید بهش دستور بدیم یا دستورش رو اجرا کنیم :)
برای روشن تر شدن، با یه مثال ملموس تر بیانش میکنم. فرض کن من و شما، شب قبلش هم دیگه رو میبینیم، بعد به هم میگیم، کلید رمز ما "12345" باشه و الگوریتم هم به این صورت باشه که هر داده ای دریافت کردیم،  با کلید جمعش کنیم و پسش بدیم. حالا فردا که هم دیگه رو میبینیم، من یه عدد تصادفی میدم به شما (مثلا 124) و شما هم یه عدد تصادفی به من میدی (مثلا 892). بعد من شما عدد من رو با 12345 جمع میکنی و نتیجه رو به من میدی، من هم عدد شما رو با 12345 جمع میکنم و نتیجه رو به شما میدم. هر دو میدونیم باید منتظر چه عددی باشیم، و اگه عددی جز اون رو دریافت کردیم متوجه میشیم که طرف مقابلمون، کسی که باید باشه نیست. ...

داخل کارت های هوشمند جدید (جاواکارت ها) این روش دوم استفاده میشه. در اصل این یه بند از استاندارد Global Platform هستش که پیشتر گفتیم از استانداردهای مدیریتی کارته. و تقریبا همه ی جاواکارت ها الزامات این استاندارد رو meet میکنند.


سوال: گفتی که سه تا کلید رمزنگاری به صورت پیش فرض روی کارت نوشته میشه، ولی الان برای احراز هویت فقط یه کلید کافی بود، پس بقیه واسه ی چیه؟ 
جواب: خب، وقتی صحبت از امنیت بین دو تا موجودیت فعال و/یا غیرفعال میشه (توی استاندارد با اسم Subject و Object شناخته میشند) دو تا مسئله ی اساسی وجود داره. یکی این که هر طرف مطمئن باشه که طرف مقابلش دقیقا همون کسی هست که فکر میکنه و بعد شروع کنه حرف بزنه یا جواب بده، دو این که حین حرف زدن/جواب دادن، کس دیگه ای نتونه محتوای صحبت هاشون رو بدست بیاره. اون سه تا کلید یکیش همون احراز هویت بالا استفاده میشه، یکیش برای رمزکردن داده های تبادلی بعد احراز هویت استفاده میشه و یکی دیگه اش وقتی استفاده میشه که ما میخوایم کلیدهای جدیدی جایگزین کلیدهای قبلی کنیم. یعنی کلیدهای جدید رو با اون کلید رمز میکنیم و ارسال میکنیم (برای بالاتر رفتن امنیت-محض احتیاط). 
هر کدوم از این کلیدها یه اسم هم دارند، به ترتیب ENC Key یا Encryption Key، و MAC Key یا Message Authentication Key و KEK یا Key Encryption Key.


آیین برادری و شرط یاری
آن نیست که عیب من هنر پنداری
آن است که گر خلاف شایسته روم
از غایت دوستیَم دشمن داری
۱۵ مهر ۹۴ ، ۰۵:۵۷ ۰ نظر موافقین ۱ مخالفین ۰
ابراهیم قاسمی

جاواکارت-مقدماتی/2-استانداردها + ساده سازی


استانداردها:

اما بعد! :دی 
معرفی استانداردها!
ما به صورت نا متناهی استاندارد داریم توی حوزه ی کارت های هوشمند و خصوصا سیمکارت ها. این استانداردها به سه دسته تقسیم میشن با اغماض:
  1. استانداردهایی که میان کانال ارتباطی رو از لحاظ فیزیکی بررسی میکنند که مثلا ولتاژ پایه ها باید اینقدر باشه و کلاک باید فرکانسش این باشه و .... یا فرکانس امواج الکترومغاطیسی برای کارت های غیرتماسی و .... ---> مهمترینش : ISO 7816 Part 3  برای کارت های تماسی و ISO 14443 برای کارت های غیرتماسی
  2. استانداردهایی که میگن مدیریت داخلی کارت باید به چه صورت باشه، مثلا حذف و نصب و تغییر کلیدرمزنگاری و ... به چه صورت هستش. ---> مهم ترینش : Global Platform برای هر دو نوع کارت های تماسی و غیر تماسی
  3.  استانداردهایی که (در واقع Specificationهایی که) APIهای جاواکارت، ویژگی های ویرچوآل ماشین جاواکارت و ویژگی های ران-تایم اِنویرومنت جاواکارت رو ارائه میدن. --> JCAPI Spec / JCRE Spec / JCVM Spec

سوال: جاواکارت با جاوا کارت فرق داره؟ :دی 
جواب: بله! جاواکارت زبون برنامه نویسی کارت هایی هستش که زبان "جاواکارت" رو ساپورت میکنند! و "جاوا کارت" همون کارت ها هستند. البته این نکته ای نیست که کسی رعایتش کنه، چیزی که باید مد نظرت باشه اینه که جاواکارت یه زبونه. :)

سوال: زبان های جاوا با جاواکارت خیلی تفاوت دارند؟ 
 جواب: هم بله هم خیر! خیر از این لحاظ که بالاخره ساختار زبان ها با هم یکی هستش و کسی که جاوا بلده، با یکم تقلا برنامه های زبان جاواکارت رو هم میفهمه. بله از این لحاظ که زبان جاواکارت به دو دلیل با جاوا تفاوت داره. دلیل اول این که قدرت سخت افزاری کارت ها با قدرت سخت افزار سیستم های معمولی قابل مقایسه نیست و بنابرین یه سری قابلیت ها از زبان جاوا حذف شده. مثلا جاواکارت ها فقط متغیر های نوع Byte و Short دارند (و int به صورت آپشنال)، در حالی که جاوا مغیرهای با سایز بزرگتر هم پشتیبانی میکنه. یا مثلا Clone کردن و ... از جاوا داخل جاواکارت نیستند. دلیل دوم هم این که به خاطر این که داخل کارت ما با حافظه ی  EEPROM و RAM به صورت غیر مستقیم سر و کار داریم و سرعت عملیات ها برامون مهمه، باید بتونیم حالت efficient بین تعریف کردن یه متغیر داخل یکی از این دو حافظه رو تشخیص بدیم.  (حافظه ی RAM موقتی هست،مقدار حجمش کمتره ولی سریع تره، حافظه ی EEPROM مقدار بزرگتری داره، کندتره و تعداد دفعات نوشتن و خوندن محدودی داره و تا پاک نکنیمش محتواش ماندگاره.)

 
 
بخش ساده سازی!

ببین عزیزم، جاواکارت رو به عنوان یه ساختمون n طبقه در نظر بگیر که پشت درب ورودیش یه سرایه دار نشسته و این سرایه دار از روزی که ساختمون ساخته میشه، تا روزی که ساختمون خراب میشه اونجاست و دو تا وظیفه داره! یکی این که هرکسی که میخواد بره توی ساختمون ساکن بشه یا کسی که ساکنه و میخواد از ساختمون بره بیرون، از این باید اجازه بگیره و کلا این کارای حمل و نقلش و خونه دادن بهش رو انجام میده. دوم این که اگه یه نفر از بیرون خواست چیزی بده به کسی که داخل ساختمونه و یا برعکس (ساکنین خواستند چیزی بدن به کسی که بیرون ساختمونه) این سرایه دار میشه واسطه!
حالا یعنی چی؟ 
کارت وقتی توی کارخونه ساخته میشه، یه اپلیکیشنی داخلش نصب میشه به اسم Card Manager یا Security Domain. این اپلیکیشن تا همیشه دیگه داخل کارت هست و از این به بعد اگه کسی خواست اپلِتی(به اپلیکیشن های روی کارت میگیم Applet) روی کارت نصب کنه، بایت-کدهاش رو به این میده و این براش نصب میکنه (همچنین واسه ی حذف یه روال مشابه طی میشه). همچنین اگه کسی خواست  دستوری/پیامی به یه اپلت روی کارت بفرسته، اول به این Card Managerمیگه من میخوام با فلان اپلت حرف بزنم، اگه Card Manager اجازه داد (اون اپلت وجود داشت، قفل نشده بود، رمز نمیخواست و...) اونوقت پیام رو میده باز به این کارت منیجر و کارت منیجر میده تش به اپلت و جواب رو میگیره و میده به کاربر بیرونی.



چه غم که عشق به جایی رسید یا نرسید؟

که آنچه زنده و زیباست، نفسِ این سفر است ...

#حسین منزوی

۱۲ مهر ۹۴ ، ۱۰:۴۹ ۲ نظر موافقین ۱ مخالفین ۰
ابراهیم قاسمی