スマートカードについては多くのことが言われていますが、最近まで物理レベルでカードとやり取りするプロセスは謎のままでした。 私の記事では、
ISO7816標準のパート3で説明されているインターフェイスを使用してスマートカードを操作する問題を強調したいと思います。 情報の抽出に多くの時間を費やしたことは正直に認めますが、すべてが非常にシンプルであることがわかりました。 興味があれば、猫の下に来てください。

ISO7816のハードウェアサポートを備えたプロセッサ(たとえばSTM32F4xx )について話していることをすぐに言わなければなりません。ソフトウェアエミュレーターの作成は依然として熱狂的です。これは、非常に強く押すか、 余暇が多すぎる場合に発生します。
結論と配線図
では、入り口には何がありますか? 次のような3ボルトの石と
ISO7816-2形式の
カード :


- VCC-電源
- RST-入力をリセット
- I / O-双方向データライン
- CLK-クロッキング
- GND-アース
- VPP-プログラミング出力
VCC入力には3つのオプションがあります:1.8 V、3 V、5 V(それぞれカードクラスA、B、C)、
RSTはカードのステートマシンをリセットする機能(アクティブレベルが低い)、
I / Oはデータライン、これは通常の
UARTであり 、
CLKはカードのプロセッサのクロックに使用されます(カードが非アクティブである場合、周波数はそれぞれ供給されません)、
VPPピンはカードのプログラムに使用されます。
これが、実際のハッカーがカードを接続する方法です。

インターフェース
インターフェイスは
USARTドライバーの同期モードです。つまり、情報の各ビットの送信を
CLKピンの周波数と同期しますが、他の同期インターフェイス(同じ
SPIなど )とは1つの重要な違いがあります。
CLKおよび372パルス(このマジックナンバーは
ISO7816の 3つの部分で記述され、
ETU (Elementary Time Unit)と呼ばれます)、つまり、1データビットが372番目(理想的な場合)のフロントごとにクロックされます。 周波数自体は1〜5 MHzの範囲にある必要があります。
それでは、データ行(
I / O )
を扱いましょう。
先ほど言ったように、これは次のパラメーターを持つ通常の
UARTです。
- データビット: 8
- ストップビット: 1.5
- パービット: 偶数(偶数)
- 速度(開始時): 9600ボー
原則として、このインターフェースのハードウェアプロパティについてこれ以上知る必要はありません。 それでは、ドライバーのセットアップに移りましょう。
ドライバーのセットアップ
ここで、
標準周辺機器ライブラリで書かれた初期化コードをすぐに投げます:
RCC_ClocksTypeDef RCC_Clocks; USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; NVIC_InitTypeDef NVIC_InitStructure;
コードが乱雑にならないように出力設定を下げましたが、1つの重要なポイントがあります。I / O出力はOpen-Drainとして構成する必要があります。標準では、カード自体がどこでプルするかを決定するときにZ状態のラインを見つける可能性があるためです。
ここでは、2つのポイント(分周前と為替レート)に焦点を当てたいと思います。 ここでの問題は何ですか? 一方では、速度を9600に設定する必要があり、他方では、システム速度の周波数倍数に設定する必要があります。
おそらく、ほとんどの場合、超低電力が不要な場合、システム周波数は最大(私の場合は168 MHz)に選択され、使用する
USARTモジュールは
APB2バスからクロックされます。その最大周波数は84 MHzであり、選択する周波数は下がるはずです1〜5 MHzの範囲で84 MHzの倍数ですが、9600の速度の場合、周波数は9600 * 372 = 3.5712 MHzになります。 ここにいる方法は? 規格の開発者はこの瞬間を提供し、公称値から最大20%の偏差を設定したため、3.5 MHzなどの周波数を静かに丸め、3500000/372 = 9409の速度を選択できます。ここでの差異は2%未満ですこれはまったく問題ありません。 除算器の値を2で割る必要があります(つまり、値1は2、2-4、3-6などによる除算に対応します)。 (84 / 3,5)/ 2 = 12を取得します:
- 周波数( CLK ):3.5 MHz
- 速度( I / O ):9409ボー
- プリスクレーア:12
さらに、私が検討したいのは、パリティエラーの処理です。 これを行うために、
ガードタイムと呼ばれる特別に用意された時間間隔があります(この国では16ビットです)。
ガードタイムとは?
ガードタイムは、パリティエラー(
NACK )の場合にレシーバが
I / Oラインに低レベルを設定する必要がある時間間隔であり、トランスミッタはこれに同じフレームを再度送信する必要があります。 この機能の有用性については特に説明しませんが、純粋に私の意見では、原則としてそのようなエラーが存在する場合、交換チャネルは信頼できないと見なされる可能性があり、そのような手段はここでは役立ちそうにありません。
ドライバーの設定では、すべてが明確であると思うので、カードとの交換を初期化するプロセスに移りましょう。
スタート
カードを開始するには、「コールド」リセットを実行する必要があります。 次のシーケンスを表します。
- RSTロー
- VCCの電源を入れます
- 周波数をCLKに送信
- 40,000 CLKサイクルの時間間隔を待ちます
- RSTハイ
- 40,000サイクルの応答を待ちます

すべてが単純で、リセットを実行し、応答を待ちます。 応答の最初のビットが40,000サイクル(t3)以内に到着しなかった場合、
RSTを Lowに設定し、
I / Oおよび
CLKを非アクティブ
にする必要があります。
ATR
この応答は何ですか?
ATR (Answer-to-Reset)は次の構造です(各フィールドのサイズは1バイトです):
- TS:頭文字
- TO:フォーマット文字
- TAi:インターフェース文字[コードFI、DI]
- TBi:インターフェース文字[コードII、PI1]
- TCi:インターフェース文字[コードN]
- TDi:インターフェース文字[コードYi + 1、T]
- T1、...、TK:歴史的キャラクター(最大15)
- TCK:チェックキャラクター
1.
TSは
開始バイトです。 次の2つの値のいずれかを取ることができます:3Fhおよび3Bh:
- 3Fh-逆変換-逆極性、つまり 0は高く送信され、1-低は送信されます(重要なポイント、奇数はパリティを制御するためにここで使用されます、つまり奇数):
- 3Bh-直接の慣習-直接の極性-同じ、しかしまったく反対(パリティ-偶数、つまり偶数)
2.
T0 フォーマットバイト 。 2オクテットで構成されます。
- Y1(高オクテット)は、続くフィールドを示すビットマスクです。
- b5-TA1が送信されます
- b6-TB1が送信されます
- b7-TC1が送信されます
- b8-TD1が送信されます
- K(低オクテット)-「履歴」バイトの数

3.
TA1 。 周波数調整のパラメーターが含まれます。
- FI(高オクテット)-配当
- DI(低オクテット)-除数

4.
TB1 。 VPP出力特性が含まれます:
- II(ビットb7-b6)-最大プログラミング電流
- PI(ビットb5-b1)-プログラミング電圧

5.
TC1 。 パラメーター
Nが含まれます-
ガード時間の追加増分(
ETU単位で設定)、0から254の値を取ることができ、255の値は、2つの隣接するフレームの最初のエッジ間の間隔が11
ETUに減少することを
意味します。
6.
TD1 ISO7816ではこのバイトの構造が明らかにされていないため、少し混乱がありますが、すべてがソースでかなりインテリジェントに記述されています[1]。 2オクテットで構成されます。
- Y2(高オクテット)は、続くフィールドを示すビットマスクです。
- b5-TA2が送信されます
- b6-TB2が送信されます
- b7-送信されたTC2
- b8-TD2が送信されます
- T(低オクテット)-使用されるプロトコル(0-T0、1-T1、その他の値は予約済み)

7.
TA2 。 有効ビットが1つ(最上位)のみ含まれ、プロトコルの別のバージョンへの切り替えの可能性を示します(0-切り替えは可能、1-切り替えは不可能)、バイトが送信されない場合、0と等しいと見なされます

8.
T1、...、TKは
履歴バイトです。 カードに関する情報、発行者、発行日時などが含まれます。このフィールドの形式は規格によって規制されていません
9.
TCK- チェックサムバイト 。 これは、前のすべてのバイトのモジュロ2(xor)加算によって計算されます(T1プロトコルにのみ存在)
ここで何が必要かを理解してみましょう。 フィールド
TA1および
TA2に最も関心があり、どのアクションをとるべきか、つまり、2つのモードのいずれかを選択する必要があることを示しています。
最上位ビットが
TA2 = 0の場合、「ネゴシエーション」モードを使用します。それ以外の場合は、指定されたモードを使用します。
Pts
ネゴシエートされた交換は、
PTS (プロトコルタイプ選択)と呼ばれるプロセスです。 このプロセスでは、ペアリングデバイスに、新しい設定を適用する準備ができたことをカードに伝えるシーケンスを送信します。 次に、カードは同じシーケンスで応答する必要があります。その後、カードとペアリングデバイスの両方が新しい設定で作業を開始できます。 適用する設定については、
ATRフレームのバイト
TA1が
通知されます。 パラメータ
Fiと
Diは値そのものではなく、テーブル内の数値です。 表から、これらの数値に対応する値
F (クロックレート変換係数)および
D (ビットレート調整係数)を見つけることができます。
Fi-Fテーブル。FI | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
F | 内部クロック | 372 | 558 | 744 | 1116 | 1488 | 1860 | RFU |
FI | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
F | RFU | 512 | 768 | 1024 | 1536 | 2048 | RFU | RFU |
テーブルDi-D。DI | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
D | RFU | 1 | 2 | 4 | 8 | 16 | RFU | RFU |
DI | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
D | RFU | RFU | 1/2 | 1/4 | 1/8 | 1/16 | 1/32 | 1/64 |
* RFU-将来の使用のために予約済みFと
Dの除算の商は、新しい
ETU値です。 任意の周波数と速度を選択できますが、それらの比率は特定の
F /
Dに等しくなければならないことを考慮してください
。PTSフレーム自体の詳細:
- PTSS:初期文字(必須)
- PTS0:フォーマット文字(必須)
- PTS1(オプション)
- PTS2(オプション)
- PTS3(オプション)
- PCK:チェックキャラクター(必須)
1.
PTSS- 開始バイト (常にFFh)
2.
PTS0- フォーマットバイト 。 フレームに存在するフィールドを決定します;最も重要なオクテットはビットマスクです:
- b5-PTS1が送信されます
- b6-PTS2が送信されます
- b7-PTS3が送信されています
- b8-常に0、予約済み
- T(低オクテット)-使用されるプロトコル(0-T0、1-T1、その他の値は予約済み)

3.
PTS1 。 バイト
TA1 ATRで受信した
Fiと
Diの要求値が含まれます。バイトが送信されない場合、
Fiと
Diは1に等しいと見なされます。

4.
PTS2 。
TC1 ATRで指定されたパラメーター
Nが適用されるかどうかを示します
。5.
PTS3 。 予約済み。
6.
PCK- チェックサムバイト 。 これは、前のすべてのバイトのモジュロ2(xor)加算によって計算されます。
簡単です。シーケンスを作成し、送信し、回答を待ち、比較し、一致する場合は、速度を
Fclk /(
F /
D )に再構築します。
カードが「ネゴシエーション」モードをサポートしていない場合、作業を続行します。
例
材料を統合するために、簡単な例を作成してみます。 これは通常のBeeline SIMカードです。 彼女が投げる
ATRは次のとおりです。
3B 3B 94 00 9B 44 20 10 4D AD 40 00 33 90 00
3Bh(TS)-直接コンベンション
3Bh(T0)(0011 1011)-「歴史的」バイト数= 11であるTA1およびTB1を想定
94h(TA1)-Fi = 9、Di = 4、テーブル1と2に従ってFとDを見つける(F = 512、D = 8)、新しいETU = 512/8 = 64
00h(TB1)-VPPはサポートされていません
この場合、PTSフレームは次のようになります。
FF 10 94 7B
FFh(PTSS)-初期バイト
10h(PTS0)(0001 0000)-PTS0、プロトコルT0を送信
94h(PTS1)= TA1
7Bh(PCK)= xor(FF 10 94)
結論
私の記事では、スマートカードのプログラミングなどの詳細を省略し、チャネルおよびアプリケーション層のプロトコルも考慮しませんでしたが、これにはいくつかの理由があります。 第一に、これらの各項目は個別の記事に基づいていますが、それ以上ではありません。第二に、私の意見では、インターネット上の
APDUプロトコルに関する情報がたくさんあります。
まあ、私は私の仕事が気付かれることなく、または少なくとも苦しんでいる人の好奇心を満たさないことを本当に願っています。 とにかく、マスターしたすべての人のおかげで、私は質問に答えて、横棒のためにいくつかの他のキックを得ることができてうれしいです。 最後に、
暗号化Javaマップに関する素晴らしい一連の記事を読むことを強くお勧めし
ます 。 すべてに良い!
リンク集