Java 代码签名证书是不是与 SSL 证书相同?

Posted

技术标签:

【中文标题】Java 代码签名证书是不是与 SSL 证书相同?【英文标题】:Are Java code signing certificates the same as SSL certificates?Java 代码签名证书是否与 SSL 证书相同? 【发布时间】:2010-09-09 21:10:40 【问题描述】:

我正在四处寻找 Java code signing 证书,这样我的 Java 小程序就不会抛出如此可怕的安全警告。然而,我发现向他们提供的所有地方都收费(在我看来)太高了,比如每年超过 200 美元。在进行研究时,代码签名证书似乎与SSL 证书几乎完全相同。

我的主要问题是:是否可以购买 SSL 证书,但用它来签署 Java 小程序?

【问题讨论】:

【参考方案1】:

简短回答:不,它们是不同的。

长答案:它是同一种证书,它使用相同的加密软件,但证书有标志,表明它被允许用于什么。代码签名和 Web 服务器是不同的用途。

【讨论】:

该死...我敢打赌他们把这些标志放在那里只是为了细分市场并收取更多费用 在一定程度上。不过,它确实有助于提高安全性。【参考方案2】:

当我在 Firefox(等)中导入新的 CA 证书时,我可以选择使用我信任的证书:

签署服务器 签署代码(如您的小程序) 签署电子邮件证书

所以对我来说答案是:是的,它们是一样的。此外,为什么不使用OpenSSL(Unix 上的 man openssl、man x509、man req 等)生成自己的?你想让警告安静下来你想让你从未见过的其他人信任你的代码吗?如果您不需要其他用户将信任链接到与他们的浏览器、操作系统等捆绑的锚 CA,则使用 OpenSSL 生成您自己的。

然后问“我如何使用 OpenSSL 来生成我自己的证书?”如果后者是您的选择。

【讨论】:

是的,我希望其他人信任小程序,因此在这种情况下,自签名并没有真正的帮助。【参考方案3】:

Thawte 提供代码签名证书here。我想其他证书颁发机构也提供这项服务。您还可以使用Java keytool 创建自签名证书。

【讨论】:

是的,我知道他们提供代码签名证书,但它们的成本太高了——一年 300 美元!我希望我可以改用更便宜的 SSL 证书,你可以花 30 美元以上 第一个链接现在断开(404)。【参考方案4】:

X.509 证书可能包括key usage fields(KU)和extended key usage fields(EKU)。 Oracle tech note describing how to create sign your RIA's 创建一个没有任何密钥使用标志的证书,它工作得很好(如果你能得到一个受信任的 CA 来签署它)

但是,越来越多的 CA 颁发带有这些关键使用字段的证书。如果存在,这些字段限制证书的使用。 java 插件检查EndEntityChecker 中是否存在这些字段:

/**
 * Check whether this certificate can be used for code signing.
 * @throws CertificateException if not.
 */
private void checkCodeSigning(X509Certificate cert)
        throws CertificateException 
    Set<String> exts = getCriticalExtensions(cert);

    if (checkKeyUsage(cert, KU_SIGNATURE) == false) 
        throw new ValidatorException
           ("KeyUsage does not allow digital signatures",
            ValidatorException.T_EE_EXTENSIONS, cert);
    

    if (checkEKU(cert, exts, OID_EKU_CODE_SIGNING) == false) 
        throw new ValidatorException
            ("Extended key usage does not permit use for code signing",
            ValidatorException.T_EE_EXTENSIONS, cert);
    

    if (!SimpleValidator.getNetscapeCertTypeBit(cert, NSCT_SSL_CLIENT)) 
        throw new ValidatorException
            ("Netscape cert type does not permit use for SSL client",
            ValidatorException.T_EE_EXTENSIONS, cert);
    

    // do not check Netscape cert type for JCE code signing checks
    // (some certs were issued with incorrect extensions)
    if (variant.equals(Validator.VAR_JCE_SIGNING) == false) 
        if (!SimpleValidator.getNetscapeCertTypeBit(cert, NSCT_CODE_SIGNING)) 
            throw new ValidatorException
                ("Netscape cert type does not permit use for code signing",
                ValidatorException.T_EE_EXTENSIONS, cert);
        
        exts.remove(SimpleValidator.OID_NETSCAPE_CERT_TYPE);
    

    // remove extensions we checked
    exts.remove(SimpleValidator.OID_KEY_USAGE);
    exts.remove(SimpleValidator.OID_EXTENDED_KEY_USAGE);

    checkRemainingExtensions(exts);

检查方法如下:

/**
 * Utility method checking if the extended key usage extension in
 * certificate cert allows use for expectedEKU.
 */
private boolean checkEKU(X509Certificate cert, Set<String> exts,
        String expectedEKU) throws CertificateException 
    List<String> eku = cert.getExtendedKeyUsage();
    if (eku == null) 
        return true;
    
    return eku.contains(expectedEKU) || eku.contains(OID_EKU_ANY_USAGE);

因此,如果未指定 KU 或 EKU,KU 或 EKU 检查器会愉快地返回 true。

但是

如果指定了 KU,数字签名KU 应该是其中之一。 如果指定了任何 EKU,则为 EKU 代码签名(由 oid 1.3.6.1.5.5.7.3.3 标识)或 EKU 任何用法(由oid 2.5.29.37.0) 也应指定。

最后,checkRemainingExtensions 方法检查剩余的关键 EKU。唯一允许出现的其他关键 EKU 是

基本约束 (oid "2.5.29.19") 和 主题替代名称 (oid 2.5.29.17)

如果发现任何其他关键 EKU,则返回 false。

【讨论】:

以上是关于Java 代码签名证书是不是与 SSL 证书相同?的主要内容,如果未能解决你的问题,请参考以下文章

代码签名证书与SSL证书区别

什么是自签名SSL证书?

ssl

ssl证书的加密算法?

自签名SSL证书是啥?有用吗

自签名SSL证书是啥?有用吗?