java - JDK 7u79 中 javax.smartcardio.Card.disconnect(boolean reset) 的行为?

标签 java smartcard

根据release notes of JRE 7u72 :

Change in javax.smartcardio.Card.disconnect(boolean reset) method behavior

Prior to the JDK 8u20 and JDK 7u72 releases, the javax.smartcardio.Card.disconnect(boolean reset) method had inverted logic for the 'reset' boolean value passed to it. The card was reset upon a disconnect if false was passed to it and vice versa. Starting with JDK 7u72 and JDK 8u20, the correct behavior as per API documentation has been implemented.

In order to provide backwards compatibility to users who rely on the old behavior, a new system property has been introduced. The following command-line option can be used to enforce the old broken behavior:

-Dsun.security.smartcardio.invertCardReset=true

This property is set by default for 7u72 and later JDK 7 update releases. By default, no behavioral change will be noticed in this area for JDK 7 update releases.

Also the following command-line option can be used to enforce the new correct behavior:

-Dsun.security.smartcardio.invertCardReset=false

This is default for 8u20 and later JDK 8 update releases. In future Java releases, the property will be ignored/disabled and default disconnect method behavior will be as specified by API.

当调用 javax.smartcardio.Card.disconnect(true) 时,即使我有 JDK 7u79,卡也不会重置。当我向 VM 传递 false 或使用选项 -Dsun.security.smartcardio.invertCardReset=true 时,一切正常。这怎么可能? JDK 7u79 是否附带了旧版本的 JRE?

最佳答案

在我看来,JRE 的行为符合预期。

拥有版本 > 7u72 的 Java 7 JRE,您必须调用 disconnect(false) 进行重置(默认情况下。这可能会被系统属性覆盖,您提到过)。这里的原因是,你必须调用 disconnect(false) 才能真正断开连接的错误已经很老了,所以相当多的软件采用并调用 disconnect(false) 来重置。如果 Oracle 在一些次要版本/bug 修复中改变了这种行为,他们就会为所有软件项目造成安全漏洞,这些软件项目通过调用 disconnect(false) 修复了他们代码中的这个 JRE/JDK bug。为此:

By default, no behavioral change will be noticed in this area for JDK 7 update releases.

(这是您从文档中引用的内容的一部分)

如果你有一些 Java 8 JRE,你必须默认调用 disconnect(true),可能会被系统属性覆盖。

因此,如果您现在想要创建一些代码,确保您的卡将被重置,这适用于 Java 7 和 8(甚至可能是更早的和即将推出的版本),您必须评估,您必须提交,即:

final static boolean TRUE;
static{
    String ven = System.getProperty("java.vendor");
    String ver = System.getProperty("java.runtime.version");
    String r = System.getProperty("sun.security.smartcardio.invertCardReset");
    TRUE=!invertReset(ven, ver, r);
}

static boolean invertReset(String vendor, String version, String reset){
    if("Oracle Corporation".equals(vendor)){
        String[] javaVersionElements = version.split("\\.|_|-b");

        //String discard = javaVersionElements[0];
        int major   = Integer.parseInt(javaVersionElements[1]);
        //String minor   = javaVersionElements[2];
        int update  = Integer.parseInt(javaVersionElements[3]);
        //String build   = javaVersionElements[4];

        // version to small for existing reset property:
        if((major == 7 && update<72) || major < 7){
            return true;
        }

        if(null != reset){
            // version recent enough and we have property:
            return "true".equals(reset);
        }else{
            // version recent enough, but no property:
            return major<8;
        }
    }
    return false;
}

现在,您可以调用 card.disconnect(TRUE);如果需要,TRUE 应该为 false。请在使用前仔细测试。 我没有。

请注意,我从 SO 文章 Getting Java version at runtime 中获取了版本检测/拆分代码

关于java - JDK 7u79 中 javax.smartcardio.Card.disconnect(boolean reset) 的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40460516/

相关文章:

c++ - 如何使用 openssl 或任何其他带有智能卡签名的库创建 PKCS7 signedData 结构?

java - 如何刷新 JTable 绑定(bind)到 MySQL 数据库

java - SharedPrefs 空指针 |这不是不可能吗?

java - 在 Servlet 上创建 ArrayList

java - 正常关闭 Grizzly 服务器的正确方法是什么? (嵌入 Jersey )

java - 数据绑定(bind) - 找不到 BR 类

java - getATR() 不会重置 javax.smartcardio 中的智能卡

java - 使用 javax.smartcardio 时,DESfire EV1 封装 APDU for PPS 命令的问题

cryptography - OpenSC 无法将 javacard 与 PKCS 小程序连接

c# - 如何更改 Mifare Classic 1k Key A 和 Key B