2009-08-10 103 views
0

我们有一个Java应用程序,它存储RSA公钥并允许用户使用任何密钥加密短信息流。该应用程序还允许用户将新密钥证书导入密钥库。当我们从一个文件中加载证书时,我们想使用通用名称(CN)作为别名。这里的问题是:从RFC1421格式化证书获得REAL X.509数据

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 

我们知道一个事实,即在文件中的主题名称混用外壳,我们需要保留该套管。有没有人知道如何从Java中的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----- 
+0

我也遇到了这个。它认为X500Principal没有提供获取DN不同部分的方法。我想解析X500Principal.getName()的结果是唯一的解决方案... – 2011-06-10 17:01:45

回答

0

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

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

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

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

+0

你是对的,断言只是为了说明的目的。 此外,我将在原始问题中发布证书。谢谢。 – 2009-08-11 16:13:55

0

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

1

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

或者,如果你映射的别名实际证书你可以存储在全部大写的“别名”(在全部大写查询它),但是你仍然必须从映射证书的原始外壳