为什么我不能将公钥证书导入到以某种方式使用keytool生成的Firefox中?

时间:2016-06-06 18:36:10

标签: certificate x509 keytool pki

我正在尝试为CA2生成证书,以便:

  1. 有一个名为CA0的根CA.
  2. 有一个名为CA1的中间CA.
  3. 还有另一个名为CA2的中间CA.
  4. CA0签署CA1证书。
  5. CA1签署CA2证书。
  6. 我使用keytool使用各种方法生成CA2。

    方法1:CA0签署CA1并写入文件; CA1签署CA2并写入文件; CA0从密钥库导出到文件

    # Start afresh
    rm -f foo.jks
    rm -f *.cer
    
    # Generate self-signed CA0 (root), CA1 (intermediate) and CA2 (another intermediate).
    keytool -genkeypair -keystore foo.jks -storepass stpass -alias ca0 -keypass kpass0 -dname CN=CA0 -ext bc=ca:true
    keytool -genkeypair -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1 -dname CN=CA1
    keytool -genkeypair -keystore foo.jks -storepass stpass -alias ca2 -keypass kpass2 -dname CN=CA2
    
    # CA0 signs CA1.
    keytool -certreq -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1 |
    keytool -gencert -keystore foo.jks -storepass stpass -alias ca0 -keypass kpass0 -ext bc=ca:true -outfile ca1.cer
    
    # CA1 signs CA2.
    keytool -certreq -keystore foo.jks -storepass stpass -alias ca2 -keypass kpass2 |
    keytool -gencert -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1 -ext bc=ca:true -outfile ca2.cer
    
    # Export CA0
    keytool -export -keystore foo.jks -storepass stpass -alias ca0 -file ca0.cer
    

    当我打开Firefox并转到偏好设置>高级>查看证书>权限,单击导入并导入ca0.cer,ca1.cer和ca2.cer一个接一个,导入正常。然后,如果我选择CA2并单击View>详细信息,我可以在“证书层次结构”窗格中看到完整的证书链。这一切都很好。

    方法2:CA0签署CA1并将其导入密钥库; CA1签署CA2并将其导入密钥库; CA0,CA1和CA2从密钥库导出到文件

    # Start afresh
    rm -f foo.jks
    rm -f *.cer
    
    # Generate self-signed CA0 (root), CA1 (intermediate) and CA2 (another intermediate).
    keytool -genkeypair -keystore foo.jks -storepass stpass -alias ca0 -keypass kpass0 -dname CN=CA0 -ext bc=ca:true
    keytool -genkeypair -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1 -dname CN=CA1
    keytool -genkeypair -keystore foo.jks -storepass stpass -alias ca2 -keypass kpass2 -dname CN=CA2
    
    # CA0 signs CA1.
    keytool -certreq -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1 |
    keytool -gencert -keystore foo.jks -storepass stpass -alias ca0 -keypass kpass0 -ext bc=ca:true |
    keytool -importcert -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1
    
    # CA1 signs CA2.
    keytool -certreq -keystore foo.jks -storepass stpass -alias ca2 -keypass kpass2 |
    keytool -gencert -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1 -ext bc=ca:true |
    keytool -importcert -keystore foo.jks -storepass stpass -alias ca2 -keypass kpass2
    
    # Export CA0, CA1 and CA2
    keytool -export -keystore foo.jks -storepass stpass -alias ca0 -file ca0.cer
    keytool -export -keystore foo.jks -storepass stpass -alias ca1 -file ca1.cer
    keytool -export -keystore foo.jks -storepass stpass -alias ca1 -file ca2.cer
    

    同样,我可以将ca0.cer,ca1.cer和ca2.cer导入Firefox中的权限。

    方法3:CA0签署CA1并将其导入密钥库; CA1签名并CA2并导出到文件; CA0和CA1从密钥库导出到文件

    # Start afresh
    rm -f foo.jks
    rm -f *.cer
    
    # Generate self-signed CA0 (root), CA1 (intermediate) and CA2 (another intermediate).
    keytool -genkeypair -keystore foo.jks -storepass stpass -alias ca0 -keypass kpass0 -dname CN=CA0 -ext bc=ca:true
    keytool -genkeypair -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1 -dname CN=CA1
    keytool -genkeypair -keystore foo.jks -storepass stpass -alias ca2 -keypass kpass2 -dname CN=CA2
    
    # CA0 signs CA1.
    keytool -certreq -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1 |
    keytool -gencert -keystore foo.jks -storepass stpass -alias ca0 -keypass kpass0 -ext bc=ca:true |
    keytool -importcert -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1
    
    # CA1 signs CA2.
    keytool -certreq -keystore foo.jks -storepass stpass -alias ca2 -keypass kpass2 |
    keytool -gencert -keystore foo.jks -storepass stpass -alias ca1 -keypass kpass1 -ext bc=ca:true -outfile ca2.cer
    
    # Export CA0 and CA1
    keytool -export -keystore foo.jks -storepass stpass -alias ca0 -file ca0.cer
    keytool -export -keystore foo.jks -storepass stpass -alias ca1 -file ca1.cer
    

    这次我可以将ca0.cer和ca1.cer导入Firefox的权限,但我无法导入ca2.cer。当我在“选择包含要导入的CA证书的文件”对话框中选择ca2.cer并单击“打开”时,根本没有任何操作。对话框消失,证书不会出现在“权限”窗格中。

1 个答案:

答案 0 :(得分:1)

keytool -export仅将链中的第一个证书写入-outfile,请参阅keytool manual

  

如果别名引用可信证书,则输出该证书。否则,别名是指具有关联证书链的密钥条目。在这种情况下,将返回链中的第一个证书。

keytool -gencert整个链写入-outfile。当您将-rfc(以PEM格式输出)添加到命令时,您可以看到:

-----BEGIN CERTIFICATE-----
MIICqDCCAmagAwIBAgIEHhRohzALBgcqhkjOOAQDBQAwDjEMMAoGA1UEAxMDQ0ExMB4XDTE2MDYw
...
hkjOOAQDBQADLwAwLAIUfkhluVSKCpemYFYfKf2KfT7UQaACFFA8SLiKbfOo6xh5e01S1YXJhM/P
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICqDCCAmagAwIBAgIEZgEJrjALBgcqhkjOOAQDBQAwDjEMMAoGA1UEAxMDQ0EwMB4XDTE2MDYw
...
hkjOOAQDBQADLwAwLAIUd2DS+rPrJqlGwziqenDdVaYQWaoCFHleJS/5XfDk+GaEMSUw53gQ0vd7
-----END CERTIFICATE-----

因此, ca2.cer包含DER格式的两个证书(CA1和CA2),只需连接即可。毫无疑问,Firefox无法处理这个问题。

我不认为有任何标准允许连接的DER证书。 PKCS#7将是证书链的通常二进制格式。连接的PEM文件也很常见,但不是DER。

keytool documentation没有说明将链写到文件中。事实上,它说" X.509证书":

  

该命令从infile读取请求(如果省略,则从标准输入中读取),使用别名的私钥对其进行签名,并将X.509证书输出到outfile(如果省略,则输出到标准输出)。

看一下sources of keytool,它会将生成的证书写入文件和链 - 不包括根目录:

dumpCert(cert, out);
for (Certificate ca: keyStore.getCertificateChain(alias)) {
    if (ca instanceof X509Certificate) {
        X509Certificate xca = (X509Certificate)ca;
        if (!isSelfSigned(xca)) {
            dumpCert(xca, out);
        }
     }
}

不包括根证书,因为处理方无论如何都会验证链到信任锚(根CA)(与SSL链验证相同的概念)。