从RFC1421格式的证书中获取REAL X.509数据

时间:2009-08-10 21:45:58

标签: java x509certificate bouncycastle jce

我们有一个存储RSA公钥的Java应用程序,允许用户使用任何密钥加密短信息流。该应用程序还允许用户将新密钥证书导入密钥库。当我们从文件加载证书时,我们希望使用公用名(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-----

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

如果您的意思是使用身份运算符(==)进行测试,那么断言应始终失败。请改用alias.equals(“CN = CommonName,OU = ...”)。

但是,假设不是问题,可以添加:

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

在代码中的适当位置并发布结果?它可能会带来更多的线索。如果没有披露任何个人识别信息,那么发布您正在加载的证书(采用文本友好的PEM格式)也会有所帮助。

答案 2 :(得分:0)

无法重现错误。你用什么JCE?我们使用Java 5和6中的Sun的JCE,我们总是在原始情况下获得DN。