2016-12-09 4 views
2

オーストリアの電子カードから姓と名字を取得しようとしています。オーストリアのeカードからResponseAPDUをXMLにデコードする方法は?

現在の動作は次のとおりです。カードにアクセスし、APDUコマンドを送信し、情報をバイト配列として取得します。

受信したバイト配列をXMLに変換して、必要なデータを抽出するにはどうすればよいですか?ここで

は、コードは次のとおりです。

import java.util.List; 

import javax.smartcardio.Card; 
import javax.smartcardio.CardChannel; 
import javax.smartcardio.CardException; 
import javax.smartcardio.CardTerminal; 
import javax.smartcardio.CommandAPDU; 
import javax.smartcardio.ResponseAPDU; 
import javax.smartcardio.TerminalFactory; 

public class Main2 { 
    public static void main(String[] args) { 
     TerminalFactory factory = TerminalFactory.getDefault(); 
     List<CardTerminal> terminals; 
     try { 
      terminals = factory.terminals().list(); 
      CardTerminal terminal = terminals.get(0); 
      Card card = terminal.connect("*"); 
      CardChannel channel = card.getBasicChannel(); 
      // Select the MF 
      byte[] aid = { (byte) 0xD0, 0x40, 0x00, 0x00, 0x17, 0x01, 0x01, 0x01 }; 
      ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x04, 0x00, aid)); 
      System.out.println("Response: " + resp.toString()); 
      // Select the Personaladata-file 
      byte[] aid2 = { (byte) 0xEF, 0x01 }; 
      resp = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x02, 0x04, aid2)); 
      System.out.println("Response: " + resp.toString()); 
      // Get the data from the file 
      resp = channel.transmit(new CommandAPDU(0x00, 0xB0, 0x00, 0x00, 0xFF)); 
      System.out.println("Response: " + resp.toString()); 
      System.out.println("Response String: " + new String(resp.getData())); 
      card.disconnect(false); 
     } catch (CardException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

答えて

3

私が(とどのようなスキーマに従って)XML構造にそのデータを変換するかどうかはわかりません。

SVPersonGrunddaten ::= SEQUENCE OF Attribute 
Attribute ::= SEQUENCE { 
    attributeName OBJECT IDENTIFIER, 
    attributeValue SET OF AttributeType } 
AttributeType ::= CHOICE { 
    numericString NumericString, 
    integer INTEGER, 
    utf8String UTF8String, 
    time GeneralizedTime, 
    printableString PrintableString } 

 
30 xxxx 
SEQUENCE 
    30 18 
    SEQUENCE 
     06 08 
     OBJECT IDENTIFIER 
      2A28000A01040101 
      => OID 1.2.40.0.10.1.4.1.1 (SV number) 
     31 0C 
     SET 
      12 0A 
      NumericString 
       nnnnnnnnddddmmmmyyyy 
       => SV number: NNNN DDMMYY 
    30 0F 
    SEQUENCE 
     06 08 
     OBJECT IDENTIFIER 
      2A28000A01040103 
      => OID 1.2.40.0.10.1.4.1.3 (Card sequence number) 
     31 03 
     SET 
      02 01 
      INTEGER 
       xx 
       => Card sequence number: xx 
    30 xx 
    SEQUENCE 
     [...] 
    30 xx 
     SEQUENCE 
     06 03 
     OBJECT IDENTIFIER 
      55042A 
      => OID 2.5.4.42 ({joint-iso-itu-t(2) ds(5) attributeType(4) givenName(42)}) 
     31 xx 
     SET 
      0C xx 
      UTF8String 
       4D69636861656C 
       => Given name: "Michael" 
    30 xx 
    SEQUENCE 
     06 03 
     OBJECT IDENTIFIER 
      550404 
      => OID 2.5.4.4 ({joint-iso-itu-t(2) ds(5) attributeType(4) surname(4)}) 
     31 xx 
     SET 
      0C xx 
      UTF8String 
       526F6C616E64 
       => Surname: "Roland" 
    30 xx 
    SEQUENCE 
     [...] 
    30 1D 
    SEQUENCE 
     06 08 
     OBJECT IDENTIFIER 
      2B06010505070901 
      => OID 1.3.6.1.5.5.7.9.1 ({iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) pda(9) dateOfBirth(1)}) 
     31 11 
     SET 
      18 0F 
      GeneralizedTime 
       yyyyyyyymmmmdddd3132303030305A 
       => Date of birth: YYYY-MM-DD 12:00:00Z 
    30 0F 
    SEQUENCE 
     06 08 
     OBJECT IDENTIFIER 
      2B06010505070903 
      => OID 1.3.6.1.5.5.7.9.3 ({iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) pda(9) gender(3)}) 
     31 03 
     SET 
      13 01 
      PrintableString 
       4D 
       => Gender: M (male) 

だから、これは以下のASN.1表記のようなものに従っているようだ。しかし、私は私のSVカードから受信したバイト配列は、ASN.1のDERのように見えるがTLV構造をエンコード指定された名前と姓の属性が

givenName Attribute ::= { 
    attributeName 2.5.4.42, 
    attributeValue { utf8String "Given Name" } 
} 
surname Attribute ::= { 
    attributeName 2.5.4.4, 
    attributeValue { utf8String "Surname" } 
} 

されるように指定された名前と姓を得るために、あなたはTLV構造、これら二つの要素のOIDのための検索を解析します

、関連付けられた値をUTF8ストリングとしてデコードします。

フィールドが正確な位置にあると仮定すると、良い考えではないようです。たとえば、特定の名前欄の前にフィールド30 xx ...(タイプAttributeのフィールド)があり、カードに印刷された学術的/専門的なタイトル(私の場合は「博士」など)がある場合にのみ存在するようです。同様に、そのような接尾辞がカードに印刷されている場合にのみ存在する学術的接尾辞(「M.Sc.」など)のための別のオプションのフィールドがあります。他のすべてのフィールドは常にカード上で同じ順序になっていますが、それが必要なのかどうかはわかりません。ここでのヒントの

1

おかげで、ただ与えられた名前のインデックス、姓、および性別フィールドは変更になる場合がありますので注意してください、そう `asn1.getObjectAt文字列

ASN1InputStream input = new ASN1InputStream(resp.getData()); 
      ASN1Primitive p; 
      try { 
       while ((p = input.readObject()) != null) { 
        // System.out.println("DEBUG: " + ASN1Dump.dumpAsString(p)); 
        // Sozialversicherungsnummer 
        ASN1Sequence asn1 = ASN1Sequence.getInstance(p); 
        ASN1Sequence seq = DLSequence.getInstance(asn1.getObjectAt(0)); 
        ASN1Set svn = DLSet.getInstance(seq.getObjectAt(1)); 
        DERNumericString svnObject = DERNumericString.getInstance(svn.getObjectAt(0)); 
        System.out.println("SVN: " + svnObject.getString()); 

        // Vorname 
        seq = DLSequence.getInstance(asn1.getObjectAt(2)); 
        svn = DLSet.getInstance(seq.getObjectAt(1)); 
        DERUTF8String stringObject = DERUTF8String.getInstance(svn.getObjectAt(0)); 
        System.out.println("Vorname: " + stringObject.getString()); 

        // Nachname 
        seq = DLSequence.getInstance(asn1.getObjectAt(3)); 
        svn = DLSet.getInstance(seq.getObjectAt(1)); 
        stringObject = DERUTF8String.getInstance(svn.getObjectAt(0)); 
        System.out.println("Vorname: " + stringObject.getString()); 

        // Geschlecht 
        seq = DLSequence.getInstance(asn1.getObjectAt(5)); 
        svn = DLSet.getInstance(seq.getObjectAt(1)); 
        DERPrintableString charObject = DERPrintableString.getInstance(svn.getObjectAt(0)); 
        System.out.println("Geschlecht: " + charObject.getString()); 
       } 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
+0

へDERのバイト配列を解読するためのコードです(2) 'は、あなたに与えられた名前などを常に与えるとは限りません。これは、たとえば、プレフィックス付きの学術タイトルまたは追加の学位のフィールドが追加されている場合です。私はちょうど私の前のカードでチェックし、タイトルやサフィックスがない場合、それらのフィールドは単に欠席しています。 –

関連する問題