有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将X509证书转换为字节(getEncoded)

我目前在这里有这段代码,但它在第16行给了我NullPointerException

byte[] frame = loadCertificate("GasClient").getEncoded();

如果我注释掉那一行,那么一切都很好——即使我把那一行留在那里,代码仍然会打印出证书。是否有其他解决方案在客户端和服务器之间发送证书?我也尝试了toString,但这给了我同样的错误

import java.io.FileInputStream;
import java.io.InputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;

public class test {
    public static X509Certificate newCert;

    public static void main(String args[]) throws Exception {
        loadCertificate("GasClient");
        byte[] frame = loadCertificate("GasClient").getEncoded();
    }

    public static X509Certificate loadCertificate(String alias) {
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            char[] password = "GasClient".toCharArray();

            try (InputStream keyStoreData = new FileInputStream(alias + "KeyStore.jks")) {
                keyStore.load(keyStoreData, password);
            }

            Key key = keyStore.getKey("Certificate-Authority", password);
            PrivateKey privateKey = (PrivateKey) key;
            System.out.println("Private Key: " + privateKey);
            java.security.cert.Certificate[] certs = keyStore.getCertificateChain(alias);

            X509Certificate newCert = (X509Certificate) certs[0];
            System.out.println(newCert);
        } catch(Exception e) {
            e.printStackTrace();
        }
        return newCert;
    }
}

共 (1) 个答案

  1. # 1 楼答案

    这是由变量阴影引起的问题。在类中有静态字段:

    public static X509Certificate newCert;
    

    但是,在try块中有以下行:

    X509Certificate newCert = (X509Certificate) certs[0];
    

    try块中的newCert与在类级别定义的newCert不同。try块中的newCert有效地隐藏或阴影在类级别声明的newCert。然后退出try块,导致其中定义的newCert超出范围。然后是return newCert,但是newCert是静态类字段。它在类加载时在概念上被初始化为null,您永远不会更改它,所以当您返回它时,您会得到null

    现在还不清楚您在类设计方面要做什么,但我假设您是Java初学者,只是在努力学习基础知识。有两个简单的解决方法。第一个是在try块中省略声明。因此,将上面的行替换为

    newCert = (X509Certificate) certs[0];
    

    第二种方法是完全去掉类字段,只从try块中返回newCert。或者,您可以在try块的正上方和外部声明newCert,并有一个退出点

    好的课堂设计当然是一个更大、更基本的话题,我在这个答案中没有提到。我只是简单地提出了一些快速解决办法

    感谢Maarten Bodewes带领我找到了bug