我想根据其公钥获取S / MIME证书的电子邮件地址和到期日期。这种方法甚至可能吗?还是我完全错了?我可以解密公共密钥以通过Java获得此类数据吗?

我在google中搜索,阅读了wiki页面,并阅读了有关oracle s / mime项目的信息。但是它并没有像它可能的那样接缝。这些数据仅在csr中可用吗?

提前致谢

最佳答案

我很惊讶这不是一个骗子,但是我找不到一个好的。

尽管Bouncy很好,并且如果要使用它也具有许多功能,但Java核心可以永远处理X.509证书。对于PEM或DER格式的文件(或任何可以作为流访问的文件)中的证书(尽管javadoc尚不清楚),您需要的是CertificateFactory

CertificateFactory fact = CertificateFactory.getInstance("X.509");

// from a real file
InputStream is = new FileInputStream ("filename");
Certificate cert = fact.generateCertificate(is);
is.close(); // or use try-resources to do automatically

// from an alternate/custom filesystem, such as a ZIP
Path p = Paths.get("somespecification"); // or any other creation of a Path
InputStream is = Files.newInputStream(p); // add open options if needed
// same as before

// from the classpath (usually a JAR)
InputStream is = ClassLoader /*or any Class<?> object*/ .getResourceAsStream("name");
// same as before

// from a byte[] in memory
InputStream is = new ByteArrayInputStream (bytearray);
// same as before, except don't really need to close

// you get the idea


尽管像这样的JCA API被定义为允许很多扩展,但是读取X.509证书实际上不仅会给您Certificate,而且会给您X509Certificate子类,.getNotAfter()会直接从该子类给出失效日期时间。电子邮件地址(如果存在)(通常不是X.509证书所必需的,但在用于S / MIME的证书中应始终如此)通常是主题名称中的一个属性,该名称实际上具有内部结构Java不允许您直接接触,因此您需要:

String x500name = ((X509Certificate)cert).getSubjectX500Principal()) .toString();
// simple case: no multivalue RDN, no reserved chars ,+="<>\;# or extra spaces
for( String attr : x500name.split(", ") )
  if( attr.startsWith("EMAILADDRESS=") )
    ... use attr.substring(13) ...
// other cases require slightly more complicated parsing


请注意,尽管许多人使用“解密”来描述任何不熟悉的密码,但X.509中根本没有加密,因此也没有实际的解密。

09-11 19:51