有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从奥地利ecard将ResponseADU解码为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();
        }
    }
}

共 (2) 个答案

  1. # 1 楼答案

    感谢您的提示,下面是将DER字节数组解码为字符串的代码

    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();
                }
    
  2. # 2 楼答案

    我不知道如何将数据转换成XML结构(以及根据什么模式)。然而,我从SV卡收到的字节数组看起来像ASN。1 DER编码的TLV结构:

    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表示法:

    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 }
    

    其中,给定名称和姓氏的属性为

    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的字段),似乎只有在卡片上打印了学术/专业头衔(如“Dr.”在我的情况下)时才会出现。同样,学术后缀还有另一个可选字段(如“M.Sc.”),只有在卡片上打印了这样的后缀时才会出现。虽然我的卡片上所有其他字段的顺序都是一样的,但我不确定这是否是必需的