Javacard 如何在 CardImpl.class 中的 checkState() 中删除和重新插入卡而不引发异常

Posted

技术标签:

【中文标题】Javacard 如何在 CardImpl.class 中的 checkState() 中删除和重新插入卡而不引发异常【英文标题】:Javacard how to remove and reinsert card without raising exception from checkState() in CardImpl.class 【发布时间】:2018-05-02 15:55:10 【问题描述】:

我无法在我的程序中找到解决此问题的方法: 我使用 JMRTD 库创建并个性化 JCOP 卡,但是,在我完成后,将关闭命令发送到服务,然后再次插入卡,任何尝试做任何事情都会让我返回卡已断开连接。我是否错过了重置标志的方法?

关于我的代码的注释: 顾名思义,ControlledDialog 是一个程序控制的对话框,因此我可以在代码的特定部分打开和关闭它。

感谢您的帮助!

我的 CardConnection 类:

package util;

import UI.MainPanel;
import UI.VerifyPanel;
import java.security.Security;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.smartcardio.CardException;
import javax.smartcardio.CardNotPresentException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.TerminalFactory;
import net.sf.scuba.smartcards.CardServiceException;
import net.sf.scuba.smartcards.TerminalCardService;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.jmrtd.PassportService;

public class CardConnection 

    static CardTerminal reader;
    static PassportService service;

    public static PassportService connectPassportService() throws CardException, CardServiceException 

        //Encontra-se a factory
        TerminalFactory terminal = TerminalFactory.getDefault();

        //listam-se os terminais
        List<CardTerminal> readers = terminal.terminals().list();

        if (readers.isEmpty()) 
            System.out.println("No Readers Found");
            System.exit(-1);
        

        //escolhe-se o primeiro
        reader = readers.get(0);

        if (GlobalFlags.DEBUG) 
            System.err.println("Reader: " + reader);

            System.err.println("Por favor insira um cartão");
        

        for (int i = 0; i < 10 && !reader.isCardPresent(); i++) 
            ControlledDialog.showMessageDialog("Por favor insira um cartão " + i, "Início");
            reader.waitForCardPresent(1000);
            System.err.println("Cartão " + (reader.isCardPresent() ? "" : "não ") + "conectado " + i);
        
        try 
            if (reader.isCardPresent()) 

                service = new PassportService(new TerminalCardService(reader));
                service.open();
                service.sendSelectApplet(false);
                BouncyCastleProvider provider = new BouncyCastleProvider();
                Security.addProvider(provider);

             else 
                throw new CardNotPresentException("Cartão não encontrado");
            
         finally 
            ControlledDialog.closeMessageDialog();
        
        return service;
    

    public static void closeConnection() 

        if (service == null) 
            return;
        
        service.close();

        try 

            if (reader.isCardPresent()) 
                if (GlobalFlags.DEBUG) 
                    System.err.println("Por favor retire o cartão");
                
                ControlledDialog.showMessageDialog("Por favor retire o cartão", "Fim");
            

            while (reader.isCardPresent()) 
                System.out.println("Remova o cartão atual");
                reader.waitForCardAbsent(100000);
            

            ControlledDialog.closeMessageDialog();

         catch (CardException ex) 
            Logger.getLogger(VerifyPanel.class.getName()).log(Level.SEVERE, null, ex);
        

        reader = null;
        service = null;

    


【问题讨论】:

【参考方案1】:

我真的不知道如何删除问题,因为这里没有足够的信息来说明正在发生的事情。通过打印调用每个函数的对象的哈希码进行仔细调试后,我发现该问题的原因是我没有更新调用这些函数的对象的“服务”字段,因此,将服务与断开连接的卡,而不是新创建的卡。 感谢理解!

【讨论】:

以上是关于Javacard 如何在 CardImpl.class 中的 checkState() 中删除和重新插入卡而不引发异常的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Javacard 制作 EMV 卡?

如何与同一物理智能卡上的多个 javacard 应用程序交互(如 yubikey)

如何在 0x6310 状态后从 JavaCard 获取更多数据?

Javacard 如何在 CardImpl.class 中的 checkState() 中删除和重新插入卡而不引发异常

Javacard 中的 ECDSA 签名

在 JavaCard 中将字节转换为短字节