Java代码签名证书和SSL证书是一样的吗?

40

我正在寻找一款Java代码签名证书,以便我的Java小程序不会出现令人惊恐的安全警告。然而,我所找到的所有提供该证书的地方都收费(在我看来)过高,比如每年超过200美元。在调研中,代码签名证书似乎与SSL证书几乎完全相同。

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

4个回答

39

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

详细回答:虽然证书类型和加密软件是相同的,但是证书含有标志以指示其所允许的用途。代码签名和Web服务器是不同的用途。


23
该死...我敢打赌他们只是为了划分市场并收取更高的费用才放置那些旗帜。 - davr
1
在某种程度上,它确实有助于安全。 - John Meagher

4
当我在Firefox(等)中导入新的CA证书时,我可以选择信任哪个证书使用:
- 签署服务器 - 签署代码(例如您的小程序) - 签署电子邮件证书
所以对我来说答案是:是的,它们是相同的。此外,为什么不使用OpenSSL(Unix上的man openssl、man x509、man req等)生成自己的证书?你想要只是消除警告还是希望其他从未见过面的人信任你的代码?如果您不需要其他用户将信任链接到其浏览器、操作系统等捆绑的锚定CA,则使用OpenSSL生成自己的证书。
如果后者是您的选择,请询问“如何使用OpenSSL生成自己的证书?”

2
是的,我希望其他人能够信任小程序,因此自签名在这种情况下并没有什么帮助。 - davr

1

X.509证书可以包含密钥使用字段(KU)和扩展密钥使用字段(EKU)。Oracle技术笔记描述如何创建签署RIA的证书创建一个没有任何密钥使用标志的证书,这很好用(如果您可以获得可信的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。

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

3
我知道他们提供代码签名证书,但是价格太高了 - 一年需要300美元!我希望能够使用更便宜的SSL证书,你可以花30美元左右买到。 - davr
第一个链接现在已经失效了(404)。 - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接