Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9551

Android HCE 調査メモ(その3)

$
0
0

目的

C#アプリでもHCEと通信できることを確認します。

環境

今回は以下の機種で動作確認しました。

Android側

  • ビルド環境

    • Android Studio 3.5.3
  • 端末

    • Sony SO-3L
    • Android 9.0 (API level 28)

PC側

  • NFCリーダ
    • ACR1251CL-NTTCom (PC/SCモードで使用)
  • OS
    • Windows 10 64bit
  • ビルド環境
    • Visual Studio 2019
  • 言語
    • C#

Android側アプリ

過去の記事を参照ください。
Android HCE 調査メモ(その1)
AIDは「F222222222」となっています。

PC側アプリ

とりあえず、.NET Core コンソールアプリで作成することにします。
(GUI等は後々…)

プロジェクト開始

Visual Studioで新規プロジェクトを作成しておきます。

NuGetパッケージ追加

UWPには標準でライブラリがあるようですが、.NET Core 用の標準ライブラリは無いようです。
そのため、NuGetパッケージの追加を行います。
ツール → NuGetパッケージマネージャー → ソリューションのNuGetパッケージの管理
「PCSC」「PCSC.Iso7816」を追加します。

ソースの作成

エラーチェック等行っていない、あまりキレイではないソースですが、とりあえず動作するソースを以下に書きます。

Program.cs
usingSystem;namespaceHCE_Test{classProgram{staticvoidMain(string[]args){varmodel=newHceModel();model.mainProcess();Console.ReadKey();}}}
HceModel.cs
usingPCSC;usingPCSC.Iso7816;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceHCE_Test{classHceModel{internalISCardContextSCardContext{get;privateset;}internalstringreaderName{get;privateset;}internalvoidmainProcess(){// 初期化Initialize();// NFCRW接続if(!ConnectNFCRW()){return;}// GET UIDgetUid();// SELECT AIDvaraid=newbyte[]{0xF2,0x22,0x22,0x22,0x22};selectAID(aid);}internalvoidInitialize(){varcontextFactory=ContextFactory.Instance;this.SCardContext=contextFactory.Establish(SCardScope.System);}internalboolConnectNFCRW(){stringtxt=string.Empty;boolresult=false;// Console.WriteLine("カードを置いてください。");// Console.ReadKey();try{// 最初に見つけたNFCRWに接続する.varreaderNames=SCardContext.GetReaders();if(IsEmpty(readerNames)){returnfalse;}readerName=readerNames[0];using(varrfidReader=SCardContext.ConnectReader(readerName,SCardShareMode.Shared,SCardProtocol.Any)){varstatus=rfidReader.GetStatus();txt+=String.Format("Reader {0}\r\n connected with protocol {1}\r\n in state {2}",status.GetReaderNames().FirstOrDefault(),status.Protocol,status.State);varatr=status.GetAtr();if(atr!=null||atr.Length>0){txt+=String.Format("\r\n Card ATR: {0}",BitConverter.ToString(atr));}}result=true;}catch(Exceptionex){txt=ex.Message;result=false;}Console.WriteLine(txt);returnresult;}internalvoidgetUid(){stringtxt=string.Empty;try{using(varrfidReader=SCardContext.ConnectReader(readerName,SCardShareMode.Shared,SCardProtocol.Any)){varapdu=newCommandApdu(IsoCase.Case2Short,rfidReader.Protocol){CLA=0xFF,Instruction=InstructionCode.GetData,P1=0x00,P2=0x00,Le=0// We don't know the ID tag size};using(rfidReader.Transaction(SCardReaderDisposition.Leave)){// Retrieving the UID .... varsendPci=SCardPCI.GetPci(rfidReader.Protocol);varreceivePci=newSCardPCI();// IO returned protocol control information.varreceiveBuffer=newbyte[256];varcommand=apdu.ToArray();intbytesReceived=rfidReader.Transmit(sendPci,// Protocol Control Information (T0, T1 or Raw)command,// command APDUcommand.Length,receivePci,// returning Protocol Control InformationreceiveBuffer,receiveBuffer.Length);// data buffervarresponseApdu=newResponseApdu(receiveBuffer,bytesReceived,IsoCase.Case2Short,rfidReader.Protocol);if((responseApdu.SW1==0x90)&&(responseApdu.SW2==0x00)){txt="UID : ";txt+=responseApdu.HasData?BitConverter.ToString(responseApdu.GetData()):"No uid received";}else{txt=string.Format("SW1: {0:X2}, SW2: {1:X2}\r\n00",responseApdu.SW1,responseApdu.SW2);}}}}catch(Exceptionex){txt=ex.Message;}Console.WriteLine(txt);}internalvoidselectAID(byte[]aid){stringtxt=string.Empty;try{using(varrfidReader=SCardContext.ConnectReader(readerName,SCardShareMode.Shared,SCardProtocol.Any)){varapdu=newCommandApdu(IsoCase.Case3Short,rfidReader.Protocol){CLA=0x00,Instruction=InstructionCode.SelectFile,P1=0x04,P2=0x00,Data=aid//AID};varcommand=apdu.ToArray();txt+=string.Format("APDU: {0}\r\n",BitConverter.ToString(command));using(rfidReader.Transaction(SCardReaderDisposition.Leave)){// Retrieving the AID .... varsendPci=SCardPCI.GetPci(rfidReader.Protocol);varreceivePci=newSCardPCI();// IO returned protocol control information.varreceiveBuffer=newbyte[256];intbytesReceived=rfidReader.Transmit(sendPci,// Protocol Control Information (T0, T1 or Raw)command,// command APDUcommand.Length,receivePci,// returning Protocol Control InformationreceiveBuffer,receiveBuffer.Length);// data buffervarresponseApdu=newResponseApdu(receiveBuffer,bytesReceived,IsoCase.Case2Short,rfidReader.Protocol);txt+=string.Format("SW1: {0:X2}, SW2: {1:X2}\r\n",responseApdu.SW1,responseApdu.SW2);if((responseApdu.SW1==0x90)&&(responseApdu.SW2==0x00)){txt+="received:";txt+=responseApdu.HasData?BitConverter.ToString(responseApdu.GetData()):"No data received";}}}}catch(Exceptionex){txt=ex.Message;}Console.WriteLine(txt);}privatestaticboolIsEmpty(ICollection<string>readerNames)=>readerNames==null||readerNames.Count<1;}}

実行結果

リーダーにHCEアプリを起動したAndroidを乗せ、アプリを実行してみます。

Reader ACS ACR1251 CL Reader PICC 0
 connected with protocol T1
 in state Specific
 Card ATR: 3B-88-80-01-00-00-00-00-80-81-71-00-79
UID : B8-65-F7-C4
APDU: 00-A4-04-00-05-F2-22-22-22-22
SW1: 90, SW2: 00
received:30-30-30-30-30-30-30-30

無事受信できました。


Viewing all articles
Browse latest Browse all 9551

Trending Articles