如何在Java中读取.pfx文件的内容?

16
我有一个名为file.pfx的文件,并且还有一个私钥。如何在Java中读取file.pfx中的证书?
我使用了以下代码:
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import javax.crypto.SecretKey;
import javax.security.auth.callback.*;
//These packages I have used.

public String readFile(String fn) { 
  String thisLine, ret = ""; 
  KeyStore ks = KeyStore.getInstance("pkcs12", "SunJSSE"); 
  ks.load(new FileInputStream(fn),"password".toCharArray()); 
  try { 
    Key key = ks.getKey("1", "password".toCharArray());
    Certificate[] cc = ks.getCertificateChain("1");
    X509Certificate certificate1 = (X509Certificate) cc[0];//Here it throws  java.lang.NullPointerException 
    ret += certificate1.getNotAfter(); 
    ret += certificate1.getNotBefore(); 
  } catch(Exception e) { 
    ret = "Cannot load, exception!";
  } 
  return ret; 
}

逐行”是什么意思?您想从PFX文件中读取证书吗?到目前为止,您尝试了什么? - Duncan Jones
1
将来请编辑您的问题以包含该信息。作为评论是无用且难以阅读的。 - Duncan Jones
好的,你已经分享了你的代码。它有什么问题 - 它不能工作吗? - Duncan Jones
谢谢你的建议。它显示警告“X509Certificate”找不到符号。我已经导入了包import java.security.*; - Banshi
java.security.cert.X509Certificate 是 Java 核心库的一部分。如果您在 IDE 中编程,它应该已经自动导入了。 - Duncan Jones
显示剩余5条评论
3个回答

8
尝试使用以下代码读取 .pfx 文件:

尝试使用以下代码读取 .pfx 文件:

  public void checkExpire() {

        try {
            KeyManagerFactory kmf = javax.net.ssl.KeyManagerFactory.getInstance("SunX509");
            KeyStore keystore = KeyStore.getInstance("PKCS12");
            char[] password= "yourfilepassword".toCharArray();

            keystore.load(new FileInputStream("filepath\filename.pfx"),password);
            //keystore.load(new FileInputStream(certificate), password);
            kmf.init(keystore, psswd);
            Enumeration<String> aliases = keystore.aliases();
            while(aliases.hasMoreElements()){
                String alias = aliases.nextElement();
                if(keystore.getCertificate(alias).getType().equals("X.509")){
                Date expDate = ((X509Certificate) keystore.getCertificate(alias)).getNotAfter();
                Date fromDate= ((X509Certificate) keystore.getCertificate(alias)).getNotBefore();
        System.out.println("Expiray Date:-"+expDate );
        System.out.println("From Date:-"+fromDate);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

7

您遇到异常的原因是您的密钥库(即PKCS #12文件)不包含使用提供的别名的证书链。

Key key = ks.getKey("1", "shalimar1234".toCharArray());
Certificate[] cc = ks.getCertificateChain("1"); // this is returning null

你的key对象很有可能也是null,但你似乎没有使用该对象。

为了了解文件中可用的别名,请尝试查看从 KeyStore.aliases() 返回的字符串。


谢谢,它有效。我使用别名。我使用以下代码:String alias = ks.aliases().nextElement(); Key key = ks.getKey(alias, "shalimar1234".toCharArray()); Certificate[] cc = ks.getCertificateChain(alias); 然后它可以正常工作。请问如何读取证书的全部内容? - Banshi
@Banshi,听起来我们已经解决了这个特定的问题。如果您有进一步的问题,请尝试自己研究解决方案。如果找不到解决方案,请发布一个新的问题。 - Duncan Jones
好的。谢谢。我也在寻找这些问题的解决方法。实际上,我是Java的新手。我是PHP开发人员和iPhone开发人员。我最近有一个PHP项目,其中有一个要求,即可移动驱动器中将有一个.pfx文件,如果可移动驱动器中存在该文件,则登录面板将打开。因此,我必须使用小程序。我已经通过file.txt文件解决了这个问题,但我从未处理过file.pfx文件系统。这就是为什么我发布这些问题的原因。而且你一直陪伴着我很长时间。如果我每次都要发布一个问题,那将是一项繁琐的任务。非常感谢。哈哈:) - Banshi

6
这里有一个关于使用Java代码打开和读取.PFX文件的论坛问题链接
总结一下链接中的内容,您应该能够像正常的JKS一样打开密钥库,但有稍微的不同,需要将密钥库类型作为pcks12,提供程序作为SunJSSE
try (FileInputStream stream = new FileInputStream("C:/store.pfx")) {
    KeyStore store = KeyStore.getInstance("pkcs12", "SunJSSE");
    store.load(stream, "password".toCharArray());

    Enumeration<String> aliases = store.aliases();

    while (aliases.hasMoreElements()) {
        System.err.println(aliases.nextElement());
    }

    X509Certificate certificate = (X509Certificate)store.getCertificate("alias");
    System.err.println(certificate.getNotAfter());
    System.err.println(certificate.getNotBefore());
    System.err.println(certificate.toString());
}

另一个有用的提示是,您可能想考虑使用并引用BouncyCastle提供程序,我个人认为它是最完整的实现。


我以前没有尝试过这个,这里有一个关于SunJSSE提供者的链接:http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider。顺便说一下,我强烈建议您考虑使用BouncyCastle作为JCE提供者。http://www.bouncycastle.org/java.html - Waleed Almadanat
仅提供链接的答案在StackOverflow上并不是很有帮助。如果您的链接在未来失效,您的答案将变得毫无意义。您能否在您的答案中总结链接内容? - Duncan Jones
使用System.err.println(certificate.toString())方法获取编码后的字符串。我怎样才能只获取证书的内容呢? - Banshi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接