我们有一个 Java 应用程序,它存储 RSA 公钥并允许用户使用任何密钥加密短信息流。该应用程序还允许用户将新的密钥证书导入到密钥库中。当我们从文件加载证书时,我们希望使用通用名称(CN)作为别名。问题是这样的:

CertificateFactory x509CertFact = CertificateFactory.getInstance("X.509");
X509Certificate cert = x509CertFact.generateCertificate(certificateInputStream);
String alias = cert.getSubjectX500Principal().getName();

assert alias.equals("CN=CommonName, OU=TestCo..."); // FAILS
assert alais.equals("cn=commonname, ou=testco..."); // PASSES

我们知道文件中的主题名称具有混合大小写,我们需要保留该大小写。有谁知道如何从 Java6 中的 JCE 获得更灵活的 X.509 支持?

我们考虑过使用 BouncyCastle 轻量级 API,但文档几乎不存在。

编辑:使用 JDK 6u11 以下是来自 java.security 的安全提供程序列表:

security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.crypto.provider.SunJCE
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.8=sun.security.smartcardio.SunPCSC
security.provider.9=sun.security.mscapi.SunMSCAPI
security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

证书:

-----BEGIN CERTIFICATE-----
MIIDHjCCAtugAwIBAgIESnr4OzALBgcqhkjOOAQDBQAwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoT
DEdlbWFsdG8gSW5jLjEnMCUGA1UECxMeU29sdXRpb25zIGFuZCBTcGVjaWFsIFByb2plY3RzMSMw
IQYDVQQDExpGUkJCTHVuYUNyeXB0b1NlcnZlci0xLjAuMDAeFw0wOTA4MDYxNTM1MjNaFw0wOTEx
MDQxNTM1MjNaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxHZW1hbHRvIEluYy4xJzAlBgNVBAsT
HlNvbHV0aW9ucyBhbmQgU3BlY2lhbCBQcm9qZWN0czEjMCEGA1UEAxMaRlJCQkx1bmFDcnlwdG9T
ZXJ2ZXItMS4wLjAwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I8
70QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJP
u6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCP
FSMLzLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV466
1FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoB
JDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOBhAACgYBHBBVNzuoXgpPFPkSN71rI
MKkSIUAVE7iLagFCklCEvHlh1UxyRhCWNh/UazaJzHRZofWlVPRGmgtl+J6BJRJIDorPqt8FfifY
fpbAbCQctMToFF5QqggumOlJozXyfV9eyYyNn+Y4yZDr8JKq70WX/S2M+Oo1+SBJsXMTeDdfkDAL
BgcqhkjOOAQDBQADMAAwLQIUA+VcqEYMHwXdKY4XC+oO/zF/pRkCFQCDKAS5HpSMazbZgToEEYft
QFJSvw==
-----END CERTIFICATE-----
有帮助吗?

解决方案

如果你的意思是你是从字面上使用的身份运营商(==)进行测试,然后断言应该总是失败。使用alias.equals( “CN =的CommonName,OU = ...”)来代替。

然而,假设这是没有问题的,还可以添加:

System.out.println(x509CertFact.getProvider());
System.out.println(alias);

在代码相应的点和后的结果?它可能会找到更多的线索。发布要装入(文本友好的PEM格式),该证书将是有益的也是如此,如果它没有透露任何个人身份信息。

其他提示

尝试使用 X500Principal#getName(字符串) 以您选择的格式获取 DN。然后你可以从中解析出通用名称。

或者,如果您将别名映射到实际证书,您可以将“别名”存储在全部大写字母中(并以全部大写字母进行查询),但您仍然会拥有映射证书中的原始大小写

不能再现错误。你用什么JCE?我们使用Sun的JCE从Java 5和6,我们总是得到DN在原来如此。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top