Jumat, Juli 10, 2009

Eksplorasi Smart Card API (MPCOS)

Translate to : by

Dokumentasi hasil eksplorasi SmartCard dengan MPCOS yang dibaca dengan PC/SC menggunakan Smart Card API dari codeproject.com.



Saya mencoba membuat kelas pembungkus (wrapper) untuk melakukan command-command sederhana:



1. Membuka/menutup koneksi ke smart card reader
2. Melakukan verifikasi secret code
3. Memilih file EF (transparent)
4. Membaca nilai biner dari file EF (transparent)
5. Meng-update nilai biner (dengan panjang nilai yang sama) dari file EF (transparent)

Pada dasarnya, hampir semua operasi (select, read, write) file smart card yang ada hanya dibedakan pada APDU command yang diberikan kepada smart card melalui PC/SC reader. Sebuah APDU command terdiri dari nilai dimana:


CLA mendefinisikan mode transmisi (secure/non secure)
INS mendefinisikan instruksi yang harus dilakukan
P1 parameter 1 dari instruksi yang diberikan (contoh: mode dari instruksi)
P2 parameter 2 dari instruksi yang diberikan (contoh: file descriptor dari file yang diproses)
Data data yang ditransmisikan (contoh: data yang akan dituliskan ke file)
Le panjang dari output/feedback yang diterima oleh program

Contoh APDU command untuk memilih (select) file bernama 3F 11 : CLA:0x00, INS:0xA4, P1:0x00, P2:0x00, Data:0x3F 0x11, Le:0x18


Referensi lebih lengkap mengenai Smart Card MPCOS dapat diperoleh di sini.
Berikut listing kode dari kelas wrapper yang saya buat:


using System;
using System.Collections.Generic;
using System.Text;
using GemCard; // smart card API

class CustomWrapper
{
#region attributes
private APDUResponse apduResp;
private CardNative iCard;
private const ushort SC_OK = 0x9000;
private const ushort SC_OK2 = 0x6112;
private const byte SC_PENDING = 0x9F;
#endregion

#region constructor
public CustomWrapper()
{
iCard = new CardNative();
}
#endregion

#region methods

// Membuka koneksi ke SmartCard PC/SC reader pertama yang ditemukan
public void Connect()
{
try
{
string[] readers = iCard.ListReaders();
iCard.Connect(readers[0], SHARE.Shared, PROTOCOL.T0orT1);
Console.WriteLine("Connects card on reader: " + readers[0]);
}
catch (Exception ex)
{
Console.WriteLine("Error when trying to connect to card reader. Error message: " + ex.Message);
}
}

// Menutup koneksi dari SmartCard reader
public void Disconnect()
{
iCard.Disconnect(DISCONNECT.Unpower);
Console.WriteLine("\nCard disconnected. Press Enter to quit...");
Console.ReadLine();
}

// Melakukan verifikasi secret code pada posisi tertentu
public void VerifySecretCode(byte[] code, byte codePos)
{
APDUCommand apduVerifySecret = new APDUCommand(0x00, 0x20, 0, codePos, code, 0);
apduResp = iCard.Transmit(apduVerifySecret);
if (apduResp.Status != SC_OK && apduResp.Status != SC_OK2)
throw new Exception("Secret code denied.");
Console.WriteLine("Secret Code Verified : " + ByteToString(code) + " in " + codePos.ToString());
}

// Memilih (menyimpan dalam memori) sebuah Elementary File
public void SelectEF(byte[] fileID)
{
APDUCommand apduSelectFile = new APDUCommand(0x00, 0xA4, 0, 0, fileID, 0x18);
apduResp = iCard.Transmit(apduSelectFile);
if (apduResp.Status != SC_OK && apduResp.Status != SC_OK2)
throw new Exception("EF selection failed.");
Console.Write("EF selected:");
Console.Write(ByteToString(fileID) + "\n");
}

// Membaca sebuah Elementary File tipe Transparent
public void ReadTransparentEF(byte[] fileID, byte fileLen)
{
this.SelectEF(fileID);
APDUCommand apduReadBinary = new APDUCommand(0x00, 0xB0, 0, 0, null, fileLen);
apduResp = iCard.Transmit(apduReadBinary);
Console.Write("Contains: ");
if (apduResp.Data != null)
{
Console.Write(ByteToString(apduResp.Data) + " or " + ByteToASCII(apduResp.Data) + "\n");
}
else
{
Console.WriteLine("Data is null");
}
}

// Mengupdate sebuah Elementary File bertipe Transparent
public void UpdateTransparentEF(byte[] fileID, byte fileLen, byte[] newVal)
{
this.SelectEF(fileID);
APDUCommand apduUpdateBinary = new APDUCommand(0x00, 0xD6, 0, 0, newVal, fileLen);
apduResp = iCard.Transmit(apduUpdateBinary);
if (apduResp.Status != SC_OK && apduResp.Status != SC_OK2)
Console.WriteLine("EF update failed");
else Console.WriteLine("EF updated");
}
#endregion

#region static method
public static String ByteToString(Byte[] byteArray)
{
String result = String.Empty;
for(int i=0;i<>

0 komentar:

:)) ;)) ;;) :D ;) :p :(( :) :( :X =(( :-o :-/ :-* :| 8-} :)] ~x( :-t b-( :-L x( =))

Posting Komentar

  © Blogger template 'A Click Apart' by Ourblogtemplates.com 2008

Back to TOP