Login  

Blog Stats

News

 誠 徵 程 式 設 計 師:
想寫程式想學程式開發系統的七年級生
團隊合作願意學習願意跟小紀一起工作
環境為三百人公司專職開發有二十餘人
意者請把履歷寄到 microchi@gmail.com  

隨筆分類

文章分類

每月文章

影像集

小玩意

小遊戲

旅遊

程式技巧


小紀的天空

using System;

using System.Text;

using System.Runtime.InteropServices;

 

  class CitizenDigitalCertificateCardNoReader

  {   

 

    public struct SCARD_IO_REQUEST

    {

      public int dwProtocol;

      public int cbPciLength;

    }

 

    //引用 PC/SC(Personal Computer/Smart Card) API WinScard.dll

    [DllImport("WinScard.dll")] public static extern int SCardEstablishContext(uint dwScope,

      int nNotUsed1, int nNotUsed2, ref int phContext);

    [DllImport("WinScard.dll")] public static extern int SCardReleaseContext(int phContext);

    [DllImport("WinScard.dll")] public static extern int SCardConnect(int hContext, string cReaderName,

      uint dwShareMode, uint dwPrefProtocol, ref int phCard, ref int ActiveProtocol);

    [DllImport("WinScard.dll")] public static extern int SCardDisconnect(int hCard, int Disposition);

    [DllImport("WinScard.dll")] public static extern int SCardListReaders(int hContext, string cGroups,

      ref string cReaderLists, ref int nReaderCount);

    [DllImport("WinScard.dll")] public static extern int SCardTransmit(int hCard,

      ref SCARD_IO_REQUEST pioSendPci, byte[] pbSendBuffer, int cbSendLength,

      ref SCARD_IO_REQUEST pioRecvPci, ref byte pbRecvBuffer, ref int pcbRecvLength);

 

    static void Main(string[] args)

    {

      int ContextHandle = 0, CardHandle = 0, ActiveProtocol = 0, ReaderCount = -1;

      string ReaderList = string.Empty; //讀卡機名稱列表

      SCARD_IO_REQUEST SendPci, RecvPci;

      byte[] SelEFAPDU = { 0x00, 0xA4, 0x02, 0x0C, 0x02, 0xFE, 0x14 }; //Select Elementary File APDU

      byte[] ReadSNAPDU = { 0x00, 0xB0, 0x00, 0x00, 0x10 }; //offset 0 讀取 0x10 Binary 資料的 APDU

      byte[] SelEFRecvBytes = new byte[2]; //應回 90 00

      int SelEFRecvLength = 2;

      byte[] SNRecvBytes = new byte[18]; //接收卡號的 Byte Array

      int SnRecvLength = 18;

 

      //建立 Smart Card API

      if (SCardEstablishContext(0, 0, 0, ref ContextHandle) == 0)

        //列出可用的 Smart Card 讀卡機

        if (SCardListReaders(ContextHandle, null, ref ReaderList, ref ReaderCount) == 0)

          //建立 Smart Card 連線

          if (SCardConnect(ContextHandle, ReaderList, 1, 2, ref CardHandle, ref ActiveProtocol) == 0)

          {

            SendPci.dwProtocol = RecvPci.dwProtocol = ActiveProtocol;

            SendPci.cbPciLength = RecvPci.cbPciLength = 8;

            //下達 Select FE14 檔的 APDU

            if (SCardTransmit(CardHandle, ref SendPci, SelEFAPDU, SelEFAPDU.Length,

              ref RecvPci, ref SelEFRecvBytes[0], ref SelEFRecvLength) == 0)

              //下達讀取卡號指令

              if (SCardTransmit(CardHandle, ref SendPci, ReadSNAPDU, ReadSNAPDU.Length,

                ref RecvPci, ref SNRecvBytes[0], ref SnRecvLength) == 0)

                Console.WriteLine("自然人憑證卡號為{0}",

                  Encoding.Default.GetString(SNRecvBytes, 0, 16));

          }

      Console.ReadKey();

    }

  }

posted on Wednesday, March 26, 2008 8:57 PM

What People Are Saying About This Post...

# re: 使用C#讀取自然人評証卡號 7/18/2008 4:49 PM Sender
請問您如果我要透過程式檢驗Pin碼是不是正確要呼叫哪個function?
感謝您

# re: 使用C#讀取自然人評証卡號 7/20/2008 12:33 PM 小紀
應該要知道驗証Pin Code 的 apdu
但我不熟 可能要有管道去內政部查吧~

# re: 使用C#讀取自然人評証卡號 1/9/2009 4:39 PM 阿龍
Verify PIN: (假設PIN碼=123456)
00 20 00 82 08 31 32 33 34 35 36 20 20

Change PIN: (假設PIN碼=123456,欲更改為87654321)
00 24 00 82 10 31 32 33 34 35 36 20 20 38 37 36 35 34 33 32 31


讀取憑證
Select G&D DF AID: (A0 00 00 00 'c' 'P' 'K' 'C' 'S' '-' '1' '5')
00 A4 04 0C 0C A0 00 00 00 63 50 4B 43 53 2D 31 35

Select EF: (4604)
00 A4 02 0C 02 46 04

Read Binary: (offset=0, length=1500)
00 B0 00 00 FA
00 B0 00 FA FA
00 B0 01 F4 FA
00 B0 02 EE FA
00 B0 03 E8 FA
00 B0 04 E2 FA


# re: 使用C#讀取自然人評証卡號 1/9/2009 4:56 PM 阿龍
前述 Verify PIN, Change PIN 等有關 PIN 碼的指令請小心使用, 沒事別亂玩!
檢驗 PIN 碼三次不過(錯三次), 就會自動鎖卡~
萬一鎖卡了, 必須帶卡到戶政事務所辦理解除...

# re: 使用C#讀取自然人評証卡號 3/23/2009 4:57 PM Kim
感謝版主的分享,不過我將你的範例完整跑一次,發現並無法完整讀回憑證卡號資料,console顯示的是『自然人憑證卡號為n』
請問版主過去開發時有遇到這樣的問題嗎?

# re: 使用C#讀取自然人評証卡號 3/23/2009 8:09 PM 小紀
沒也~

你要不要把 SNRecvBytes Dump 出來看看?

# re: 使用C#讀取自然人評証卡號 3/25/2009 3:43 PM Kim
小紀大大,
我剛剛在以下這段code debug
//下達讀取卡號指令

if (SCardTransmit(CardHandle, ref SendPci, ReadSNAPDU, ReadSNAPDU.Length,

ref RecvPci, ref SNRecvBytes[0], ref SnRecvLength) == 0)


看到的 SNRecvBytes ,維度為18,
資料為 109,0,~~~~ 0 (後面都是0)

# re: 使用C#讀取自然人評証卡號 3/25/2009 3:47 PM Kim
更正,是110,0~~~~0(後面都是0)

# re: 使用C#讀取自然人評証卡號 3/25/2009 4:49 PM 小紀
那 SelEFRecvBytes 呢?

# re: 使用C#讀取自然人評証卡號 3/30/2009 5:52 PM Kim
抱歉這麼晚回覆,線在測試時發現似乎無法連線了,也許是本身機器問題,
執行
//建立 Smart Card API
if (SCardEstablishContext(0, 0, 0, ref ContextHandle) == 0)
回傳值是-2146435043
看來我得先處理這部份了。


# re: 使用C#讀取自然人評証卡號 3/30/2009 7:30 PM 小紀
加油囉~

# re: 使用C#讀取自然人評證卡號 4/9/2009 10:43 AM S
您好:
請問身份證字號,取得出來嗎?

# re: 使用C#讀取自然人評証卡號 5/20/2009 1:42 PM 阿龍
回傳值 -2146435043 等於 0x8010001D
這是 PC/SC API (winscard.dll) 的回應碼
發生原因是你的PC沒有安裝SmartCard服務
或SmartCard服務尚未啟動

# re: 使用C#讀取自然人評証卡號 5/20/2009 1:46 PM 阿龍
自然人憑證只存身份證字號的最後四碼


# re: 使用C#讀取自然人評証卡號 5/21/2009 10:55 AM 小紀
龍哥, 交個朋友吧~ 我的Email: microchi@gmail.com

# re: 使用C#讀取自然人評証卡號 5/22/2009 1:09 PM 阿龍
ok!
我也有gmail: alan5666@gmail.com

# re: 使用C#讀取自然人評証卡號 9/18/2009 12:06 AM skk
最近電視一直播工商憑證要全面發,請問有工商憑證的範例嗎?

# re: 使用C#讀取自然人評証卡號 11/5/2009 11:04 AM 阿龍
工商憑證我不清楚, 不過我猜測應該是和自然人憑證相似

# ????????????????????????????????????????????? | ???????????? Blog 12/11/2009 4:57 PM Pingback/TrackBack
????????????????????????????????????????????? | ???????????? Blog

# re: 使用C#讀取自然人評証卡號 1/9/2010 9:31 AM 炙日
Kim :
你把SamrtCard的服务开启就可以了。

# re: 使用C#讀取自然人評証卡號 1/9/2010 9:31 AM 炙日
Kim :
你把SamrtCard的服务开启就可以了。

# ??????Smart Card???APDU Command | ???????????? Blog 2/13/2010 2:33 PM Pingback/TrackBack
??????Smart Card???APDU Command | ???????????? Blog

What do you have to say?

Title:
Name:
Url:
驗證碼  
Comments: