【问题标题】:SunPKCS11 provider in MacOS for FirefoxMacOS for Firefox 中的 SunPKCS11 提供程序
【发布时间】:2017-11-10 20:08:27
【问题描述】:

我设法让SunPKCS11 在 Windows 下与 Firefox ESR 52.0 一起工作,但我无法让它在 MacOS 中加载。我已经尝试了几种不同的配置并通过PKCS11 直接加载它,但没有任何效果,谁能给我一些指导?

pkcs11.cfg配置如下:

name = FirefoxKeyStore
library = "/Applications/Firefox.app/Contents/MacOS/fixed-for-java-runtime/libsoftokn3.dylib"
attributes = compatibility
nssArgs = "configdir='/Users/helloworld/Library/Application Support/Firefox/Profiles/wasdwasd.default-1453211557245' certPrefix='' keyPrefix='' secmod='secmod.db' flags='readOnly' "
slot = 2

然后在 Java 中,我尝试像这样加载它:

FileInputStream fis = new FileInputStream("pkcs11.cfg");
Provider provider = new SunPKCS11(fis);
Security.addProvider(provider);

但是这立即给了我以下错误:

sunpkcs11: Initializing PKCS#11 library /Applications/Firefox.app/Contents/MacOS/fixed-for-java-runtime/libsoftokn3.dylib
sunpkcs11: Multi-threaded initialization failed: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DEVICE_ERROR
Exception in thread "main" java.security.ProviderException: Initialization failed
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:376)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:107)

您可能会问我为什么要从奇怪的文件夹中加载 .dylib,那是因为我在 MacOS 中使用 install_name_tool@executable_path 更改为 @loader_path 以使库依赖项工作(因为我'我试图在 Eclipse 中而不是从 Firefox 本身中运行它)。

我也尝试使用这里建议的解决方案:How to finalize SunPKCS11 Provider after it is initialized?,但它也是不行的......我得到了同样的错误。

除了尝试这里提到的各种不同的配置设置:https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/PKCS11/Module_Specs#Softoken_Specific_Parameters

EDIT1

我尝试了@FaithReaper 提到的方法,但它仍然抛出同样的错误。我尝试将槽值更改为01-1,结果相同。加载底层PKCS11 对象时似乎存在问题。

Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DEVICE_ERROR
at sun.security.pkcs11.wrapper.PKCS11.C_Initialize(Native Method)
at sun.security.pkcs11.wrapper.PKCS11$SynchronizedPKCS11.C_Initialize(PKCS11.java:1545)
at sun.security.pkcs11.wrapper.PKCS11.getInstance(PKCS11.java:157)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:330)

我不知道这是否有帮助,但我在 FireFox 配置文件上运行了 modutil 并正在转储此信息:

modutil -dbdir "/Users/eto/Library/Application Support/Firefox/Profiles/ew2g332o.default-1453211557245" -rawlist

library= name="NSS Internal PKCS #11 Module" 
parameters="configdir=/Users/eto/Library/Application Support/Firefox/Profiles/ew2g332o.default-1453211557245 certPrefix= keyPrefix= secmod=secmod.db flags=readOnly " 
NSS="Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})"

PKCS #11 模块列表

  1. NSS 内部 PKCS #11 模块 uri: pkcs11:library-manufacturer=Mozilla%20Foundation;library-description=NSS%20Internal%20Crypto%20Services;library-version=3.33 插槽:2 个插槽状态:已加载

    槽:NSS 内部加密服务令牌:NSS 通用加密 服务 URI: pkcs11:token=NSS%20Generic%20Crypto%20Services;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

    槽:NSS 用户私钥和证书服务令牌:NSS 证书数据库 uri: pkcs11:token=NSS%20Certificate%20DB;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

【问题讨论】:

    标签: java macos firefox pkcs#11


    【解决方案1】:

    首先,我注意到您插入/添加Provider 的方式与我不同。您可以尝试以这种方式添加Provider 吗? (可能无关紧要)

    Provider p = new SunPKCS11(new ByteArrayInputStream(config.getBytes()));
    Security.insertProviderAt(p, 1);
    KeyStore.Builder builder = null;
    builder = KeyStore.Builder.newInstance("PKCS11", p, 
        new KeyStore.CallbackHandlerProtection(new UtilTarjetas().new CustomCallbackHandler()));
    cardKeyStore = builder.getKeyStore();
    

    那么,或许你可以试试这里的方法:

    https://github.com/avocado-framework/avocado/issues/1112

    即:

    apahim 于 2016 年 4 月 7 日发表评论

    @will-Do,nss 人员能够追踪此问题,并且似乎他们将考虑更改 NSS_InitContext(),其中应在 fork() 之后包含 SECMOD_RestartModules(PR_FALSE)。无论如何,他们还提供了比我提供给您的解决方法更好的解决方法。如果您将环境变量NSS_STRICT_NOFORK 设置为DISABLED,那么代码应该可以工作。它对我有用,我想检查它是否也对你有用。期待看到您的结果。

    此外,一些消息来源表明这可能是令牌或插槽问题。您可以尝试将插槽索引更改为0-1

    【讨论】:

    • 首先感谢您的帮助。但问题似乎在于初始化SunPKCS11 级别,它在我什至insertProviderAtaddProvider 之前抛出CKR_DEVICE_ERRORCKR_DEVICE_ERROR 正在被sun.security.pkcs11.wrapper.PKCS11.C_Initialize(Native Method) 抛出,请参阅我在帖子中的更新。
    【解决方案2】:

    如果在 FireFox 之外执行,则 Mac OS X 中 Firefox 提供的库实际上可能完全损坏或无法正常工作。

    在尝试了许多不同的配置和方法组合后,我终于不使用 Firefox 的库...

    以下是让它工作的分步方法:

    1. 在你的 Mac 上安装 homebrew
    2. 运行brew install nss
    3. 运行brew install nspr
    4. 您可能需要手动将它们与brew link nssbrew link nspr 链接
    5. 在配置文件中,你需要将它指向你的自制软件libsoftokn3.dylib,就像这样library = /usr/local/opt/nss/lib/libsoftokn3.dylib

    那么您的 Java 代码应该能够在 Mac OS X 下加载 Firefox 密钥库...我已经提交了一个错误 here。票证包含一个有效的sample code,说明如何实例化 PKCS11、加载 Firefox 密钥库并列出存储中的别名。

    使用 Firefox 绝对是一场噩梦……但至少我让它工作了……谁能想到他们提供的库不起作用(但它在 Windows 中起作用!)? :P

    为了完整起见,我也直接在这篇文章中包含了示例代码:

    import java.io.ByteArrayInputStream;
    import java.security.KeyStore;
    import java.security.Provider;
    import java.security.Security;
    import java.util.Collections;
    
    public class Sample {
    
        private KeyStore load(String lib, String profile) throws Exception
        {
            String config = "library = " + lib + "\n" + 
                    "name = FirefoxKeyStore\n" + 
                    "attributes = compatibility\n" + 
                    "nssArgs = \"configDir='" + profile + "' certPrefix='' keyPrefix='' secmod='secmod.db' flags='readOnly,forceOpen,optimizeSpace' \"\n" + 
                    "slot = 2\n";
    
            ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes());
            Provider provider = new sun.security.pkcs11.SunPKCS11(bais);
            Security.addProvider(provider);
    
            return KeyStore.getInstance("PKCS11");
        }
    
        public static void main(String[] args) throws Exception {
    
            Sample s = new Sample();
    
            String profile = "/Users/blah/Library/Application Support/Firefox/Profiles/yougottachangethis";
            String[] libs = { 
                //"/Applications/Firefox.app/Contents/MacOS/libsoftokn3.dylib",
                "/usr/local/opt/nss/lib/libsoftokn3.dylib"
            };
    
            for (String lib : libs) {
                System.out.println("TRYING >>> " + lib);
                try {
                    KeyStore ks1 = s.load(lib, profile);
    
                    ks1.load(null, null);
                    for (String alias : Collections.list(ks1.aliases())) {
                        System.out.println(alias);  
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
    

    这是来自 Mac 的 otool 的输出(包含在 FaithReaper 的 cmets 中):

    otool -L libsoftokn3.dylib
    libsoftokn3.dylib:
    /usr/local/opt/nss/lib/libsoftokn3.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 253.0.0)
    /usr/local/Cellar/nss/3.34/lib/libnssutil3.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/local/opt/nspr/lib/libplc4.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/local/opt/nspr/lib/libplds4.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/local/opt/nspr/lib/libnspr4.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
    

    【讨论】:

    • 我忘了说但是你如何配置系统环境变量LD_LIBRARY_PATH?毫无疑问,nss 依赖于nspr
    • 我不确定 Mac 加载库是否与 Linux 不同,但我的 LD_LIBRARY_PATH 是空白的,当我使用 otool -L libsoftokn3.dylib 时,我可以看到它已经链接到 /usr/local/opt/nspr/lib/libnspr4.dylib
    • 嗯.....我认为libsoftokn3.so位于nss的文件夹中,而不是nspr,Linux中的名称是原样的,没有链接到libnspr4.so。所以这可能是问题所在。添加此系统变量,指向您拥有libsoftokn3.dylib 的文件夹(不是链接,而是真实文件),然后重试。你能调查一下 nss 所在的位置吗?
    • 如果您查看我的示例,libsoftokn3.dylib 已经在 nss 文件夹中。请参阅/usr/local/opt/nss/lib/libsoftokn3.dylib,这是 homebrew 链接它的方式。
    猜你喜欢
    • 1970-01-01
    • 2018-05-04
    • 2019-05-05
    • 2022-06-30
    • 1970-01-01
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多