我们有一个存储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-----
答案 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。