首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用多个读卡器加载PKCS密钥存储库时出错

用多个读卡器加载PKCS密钥存储库时出错
EN

Stack Overflow用户
提问于 2020-03-20 18:15:04
回答 1查看 1.1K关注 0票数 1

我遇到了一个奇怪的问题,当阅读卡,在一个多终端的设置,从N(除外1)终端。

环境- JDK8_u211,没有任何读卡器的Destop,笔记本电脑内部读卡器,USB读卡器,CAC\PIV卡

用例试过

  1. 当CAC卡插入笔记本电脑的内部插槽时,一切都能正常工作,并将USB卡终端连接到笔记本电脑上。
  2. 当CAC卡插入USB读取器并连接到桌面时,一切都正常。
  3. 当CAC卡插入USB读取器并连接到膝上型计算机时,PKCS存储实例化失败,因为配置使用slot=1。
  4. 当CAC卡插入USB读取器并连接到膝上型计算机(如果我硬编码配置中的slot=4 )时,一切正常。

问题:无法确定配置文件中要使用的正确插槽。不知何故,终端的数量并不能在运行时加起来来确定时隙。

通过启用JDK调试日志,我可以在内部验证"C_GetSlotList"返回0,4,因为我只有两个终端,因此使用索引0或1。

有没有人知道如何确定终端和插槽之间的相关性,或者我试图读卡片的方式有什么问题吗?

请给我建议。

样本代码

代码语言:javascript
复制
    public class MultipleTerminals {

    private static String DLL_PATH = "C:\\opensc-pkcs11.dll";

    public static void main(String[] args) throws Exception {

        MyTerminal custTerminalObj = getSmartCardTerminal();
        CardTerminal terminal = custTerminalObj.getTerminal();
        Integer terminalIdx = custTerminalObj.getIndex();
        System.out.println("Using Terminal.Name: " + terminal.getName());
        System.out.println("Using Terminal.isCardPresent: " + ((CardTerminal)terminal).isCardPresent());

         if (terminal.isCardPresent()) { // duplicate check
             registerProvider(4);
             KeyStore keyStore = createKeyStore();
             printCertificate(keyStore);
         }
    }

    public static MyTerminal getSmartCardTerminal() {
        System.out.println("---------------------------------------------------");
        MyTerminal terminal = null;
        int terminalIdx = -1;
        try {
            TerminalFactory factory = TerminalFactory.getDefault();
            if (factory != null) {
                List<CardTerminal> allTerminals = factory.terminals().list();
                for(CardTerminal term : allTerminals) {
                    System.out.println("Terminal Name: " + term.getName());
                    System.out.println("isCardPresent: " + term.isCardPresent());
                    System.out.println("----------");                   
                }
                for(CardTerminal term : allTerminals) {
                    terminalIdx++;
                    if(term.isCardPresent()) {
                        terminal = new MyTerminal();
                        terminal.setIndex(terminalIdx);
                        terminal.setTerminal(term);
                        System.out.println("Using Terminal Idx: " + terminalIdx);
                    }
                }
            }
        } catch (CardException e1) {
            terminal = null;
            System.out.println("SmartCardHelper.getSmartCardTerminal --> "
                    + "Exception while accessing smart-card terminal: "
                    + e1.getMessage());
            e1.printStackTrace();
        }

        return terminal;
    }

    public static void registerProvider(Integer idx) {
        System.out.println("---------------------------------------------------");
        String ext = "attributes(*,*,*)=\n{\nCKA_TOKEN=true\nCKA_LOCAL=true\n}";
        String OPENSC_DEFAULT_PROVIDER_NAME = "PKCS#11";
        String OPENSC_PKCS11_DLL = DLL_PATH;
        String configString = "name = "
                + OPENSC_DEFAULT_PROVIDER_NAME.replace(' ', '_') + "\n"
                + "library = "
                + OPENSC_PKCS11_DLL + "\n slot = " + idx + " "
                + "\n attributes = compatibility \n" + ext;

        System.out.println("\tConfigString: " + configString);

        ByteArrayInputStream is = new ByteArrayInputStream(
                configString.getBytes(Charset.defaultCharset()));

        Provider cardSecurityProvider = new sun.security.pkcs11.SunPKCS11(
                is);

        displayProviders();
        Security.addProvider(cardSecurityProvider);
        displayProviders();
        System.out.println("==================");
    }


    public static KeyStore createKeyStore() throws KeyStoreException {
        KeyStore.CallbackHandlerProtection callbackHandler = new KeyStore.CallbackHandlerProtection(
                new PIVCardPinHandler());
        KeyStore.Builder builder = KeyStore.Builder.newInstance("PKCS11", null,
                callbackHandler);
        return builder.getKeyStore();
    }

    public static void displayProviders() {
        System.out.println("---------------------------------------------------");
        Provider[] objs = Security.getProviders();
        System.out.println("Provider Count: " + objs.length);

        String type = "KeyStore";
        String algorithm="PKCS11";
        ProviderList list = Providers.getProviderList();
        Provider provider = list.getProvider("SunPKCS11-PKCS");
        System.out.println("Provider[SunPKCS11-PKCS]: " + provider);

        if(provider != null) {
            Set<Service> svcs = provider.getServices();
            System.out.println("Service count: " + svcs.size());
        }

        Service firstService = list.getService(type, algorithm);
        System.out.println("Type[KeyStore], Algo[PKCS11], Service: " + firstService);       
    }

    public static void printCertificate(KeyStore keyStore)
            throws KeyStoreException {
        for (String alias : Collections.list(keyStore.aliases())) {
            System.out.println("Alias: " + alias);
        }
    }
}


class MyTerminal{

    private Integer index;
    private CardTerminal terminal;

    public MyTerminal() {
    }

    public Integer getIndex() {
        return index;
    }
    public void setIndex(Integer index) {
        this.index = index;
    }
    public CardTerminal getTerminal() {
        return terminal;
    }
    public void setTerminal(CardTerminal terminal) {
        this.terminal = terminal;
    }   
}

* Output TestCase-1 (工作)*

代码语言:javascript
复制
---------------------------------------------------
Terminal Name: Alcor Micro USB Smart Card Reader 0
isCardPresent: true
----------
Terminal Name: Identive SCR33xx v2.0 USB SC Reader 0
isCardPresent: false
----------
Using Terminal Idx: 0
Using Terminal.Name: Alcor Micro USB Smart Card Reader 0
Using Terminal.isCardPresent: true
---------------------------------------------------
    ConfigString: 
name = PKCS#11
library = C:\opensc-pkcs11.dll
 slot = 0 
 attributes = compatibility 
attributes(*,*,*)=
{
CKA_TOKEN=true
CKA_LOCAL=true
}
SunPKCS11 loading ---DummyConfig-1---
sunpkcs11: Initializing PKCS#11 library C:\opensc-pkcs11.dll
Information for provider SunPKCS11-PKCS
Library info:
  cryptokiVersion: 2.20
  manufacturerID: DUMMY_VALUE                  
  flags: 0
  libraryDescription: DUMMY_VALUE      
  libraryVersion: 0.19
All slots: 0, 4
Slots with tokens: 0, 4
Slot info for slot 0:
  slotDescription: Alcor Micro USB Smart Card Reader 0                             
  manufacturerID: DUMMY_VALUE
  flags: CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT
  hardwareVersion: 0.00
  firmwareVersion: 0.00
Token info for token in slot 0:
  label: DUMMY_VALUE            
  manufacturerID: DUMMY_VALUE                          
  model: PKCS#15 emulated
  serialNumber: DUMMY_VALUE
  flags: CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED
  ulMaxSessionCount: CK_EFFECTIVELY_INFINITE
  ulSessionCount: 0
  ulMaxRwSessionCount: CK_EFFECTIVELY_INFINITE
  ulRwSessionCount: 0
  ulMaxPinLen: 8
  ulMinPinLen: 4
  ulTotalPublicMemory: CK_UNAVAILABLE_INFORMATION
  ulFreePublicMemory: CK_UNAVAILABLE_INFORMATION
  ulTotalPrivateMemory: CK_UNAVAILABLE_INFORMATION
  ulFreePrivateMemory: CK_UNAVAILABLE_INFORMATION
  hardwareVersion: 0.00
  firmwareVersion: 0.00
  utcTime: 
---------------------------------------------------
Provider Count: 10
Provider[SunPKCS11-PKCS]: null
Type[KeyStore], Algo[PKCS11], Service: null
---------------------------------------------------
Provider Count: 11
Provider[SunPKCS11-PKCS]: SunPKCS11-PKCS version 1.8
Service count: 26
Type[KeyStore], Algo[PKCS11], Service: SunPKCS11-PKCS: KeyStore.PKCS11 -> sun.security.pkcs11.P11KeyStore
  aliases: [PKCS11-PKCS]
 (KeyStore)
==================
sunpkcs11: caller passed NULL pin

* Output TestCase-3 (不工作)*

代码语言:javascript
复制
---------------------------------------------------
Terminal Name: Alcor Micro USB Smart Card Reader 0
isCardPresent: false
----------
Terminal Name: Identive SCR33xx v2.0 USB SC Reader 0
isCardPresent: true
----------
Using Terminal Idx: 1
Using Terminal.Name: Identive SCR33xx v2.0 USB SC Reader 0
Using Terminal.isCardPresent: true
---------------------------------------------------
    ConfigString: 
name = PKCS#11
library = C:\opensc-pkcs11.dll
 slot = 1 
 attributes = compatibility 
attributes(*,*,*)=
{
CKA_TOKEN=true
CKA_LOCAL=true
}
SunPKCS11 loading ---DummyConfig-1---
sunpkcs11: Initializing PKCS#11 library C:\opensc-pkcs11.dll
Information for provider SunPKCS11-PKCS
Library info:
  cryptokiVersion: 2.20
  manufacturerID: DUMMY_VALUE                  
  flags: 0
  libraryDescription: DUMMY_VALUE      
  libraryVersion: 0.19
All slots: 0, 4
Slots with tokens: 0, 4
---------------------------------------------------
Provider Count: 10
Provider[SunPKCS11-PKCS]: null
Type[KeyStore], Algo[PKCS11], Service: null
---------------------------------------------------
Provider Count: 11
Provider[SunPKCS11-PKCS]: SunPKCS11-PKCS version 1.8
Service count: 0
Type[KeyStore], Algo[PKCS11], Service: null
==================
Exception in thread "main" java.security.KeyStoreException: KeyStore instantiation failed
    at java.security.KeyStore$Builder$2.getKeyStore(KeyStore.java:1967)

Caused by: java.security.KeyStoreException: PKCS11 not found
    at java.security.KeyStore.getInstance(KeyStore.java:851)
    at java.security.KeyStore$Builder$2$1.run(KeyStore.java:1923)
    at java.security.KeyStore$Builder$2$1.run(KeyStore.java:1918)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.KeyStore$Builder$2.getKeyStore(KeyStore.java:1964)
    ... 2 more
Caused by: java.security.NoSuchAlgorithmException: PKCS11 KeyStore not available
    at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
    at java.security.Security.getImpl(Security.java:695)
    at java.security.KeyStore.getInstance(KeyStore.java:848)
    ... 6 more

* Output TestCase-4 (工作)*

代码语言:javascript
复制
---------------------------------------------------
Terminal Name: Alcor Micro USB Smart Card Reader 0
isCardPresent: false
----------
Terminal Name: Identive SCR33xx v2.0 USB SC Reader 0
isCardPresent: true
----------
Using Terminal Idx: 1
Using Terminal.Name: Identive SCR33xx v2.0 USB SC Reader 0
Using Terminal.isCardPresent: true
---------------------------------------------------
    ConfigString: 
name = PKCS#11
library = C:\opensc-pkcs11.dll
 slot = 4 
 attributes = compatibility 
attributes(*,*,*)=
{
CKA_TOKEN=true
CKA_LOCAL=true
}
SunPKCS11 loading ---DummyConfig-1---
sunpkcs11: Initializing PKCS#11 library C:\opensc-pkcs11.dll
Information for provider SunPKCS11-PKCS
Library info:
  cryptokiVersion: DUMMY_VALUE
  manufacturerID: DUMMY_VALUE                  
  flags: 0
  libraryDescription: DUMMY_VALUE      
  libraryVersion: DUMMY_VALUE
All slots: 0, 4
Slots with tokens: 0, 4
Slot info for slot 4:
  slotDescription: DUMMY_VALUE                           
  manufacturerID: DUMMY_VALUE
  flags: CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT
  hardwareVersion: 0.00
  firmwareVersion: 0.00
Token info for token in slot 4:
  label: DUMMY_LABEL            
  manufacturerID: DUMMY_VALUE                          
  model: PKCS#15 emulated
  serialNumber: DUMMY_VALUE
  flags: CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED
  ulMaxSessionCount: CK_EFFECTIVELY_INFINITE
  ulSessionCount: 0
  ulMaxRwSessionCount: CK_EFFECTIVELY_INFINITE
  ulRwSessionCount: 0
  ulMaxPinLen: 8
  ulMinPinLen: 4
  ulTotalPublicMemory: CK_UNAVAILABLE_INFORMATION
  ulFreePublicMemory: CK_UNAVAILABLE_INFORMATION
  ulTotalPrivateMemory: CK_UNAVAILABLE_INFORMATION
  ulFreePrivateMemory: CK_UNAVAILABLE_INFORMATION
  hardwareVersion: 0.00
  firmwareVersion: 0.00
  utcTime: 
---------------------------------------------------
Provider Count: 10
Provider[SunPKCS11-PKCS]: null
Type[KeyStore], Algo[PKCS11], Service: null
---------------------------------------------------
Provider Count: 11
Provider[SunPKCS11-PKCS]: SunPKCS11-PKCS version 1.8
Service count: 26
Type[KeyStore], Algo[PKCS11], Service: SunPKCS11-PKCS: KeyStore.PKCS11 -> sun.security.pkcs11.P11KeyStore
  aliases: [PKCS11-PKCS]
 (KeyStore)
==================
sunpkcs11: caller passed NULL pin
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-23 01:46:19

时隙id时隙索引之间的混淆。它们是两种不同的属性。

C_GetSlotList为您提供一个slot id's数组,而不是时隙索引。在您的示例中,04是时隙id的,而不是时隙索引。槽索引是数组中时隙id的索引。

在要标识索引的getSmartCardTerminal()方法中,您要标识索引,但在registerProvider(Integer idx)方法中,您要将索引映射为id,如下所示:

OPENSC_PKCS11_DLL + "\n 插槽=“+ idx +”“

当您使用时隙索引时,您应该使用slotListIndex,当您使用时隙id时,您应该使用slot

因此,要解决问题,请将其更改为:

slotListIndex =“+ OPENSC_PKCS11_DLL +”

文档这里

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60779561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档