Преобразование X509Certificate в байт (getEncoded) - PullRequest
0 голосов
/ 09 мая 2020

Сейчас у меня есть этот код, но он дает мне исключение NullPointerException в строке 16.

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 голос
/ 09 мая 2020

Это проблема, вызванная затенением переменных. В классе у вас есть поле stati c:

public static X509Certificate newCert;

Однако в блоке try у вас есть следующая строка:

X509Certificate newCert = (X509Certificate) certs[0];

newCert в блоке try не то же самое, что newCert, определенное на уровне класса. newCert в блоке try эффективно скрывает или затеняет newCert, объявленный на уровне класса. Затем вы выходите из блока try, в результате чего newCert, определенный в нем, становится go вне области видимости. Тогда вы return newCert, но это newCert - это поле класса stati c. Концептуально он инициализируется нулевым значением во время загрузки класса, и вы никогда не меняете его, поэтому, когда вы его вернете, вы получите null.

Не совсем понятно, что вы пытаетесь сделать здесь с дизайном класса, но я ' Предположим, вы Java новичок и изо всех сил пытаетесь выучить основы. Есть два простых решения. Первый - оставить объявление внутри блока try. Поэтому замените указанную выше строку на

newCert = (X509Certificate) certs[0];

Вторая - полностью избавиться от поля класса и просто вернуть newCert из блока try. В качестве альтернативы вы можете объявить newCert чуть выше и за пределами блока try и иметь единую точку выхода.

Хороший дизайн класса - это, конечно, более крупный и фундаментальный topi c, а у меня нет обратился к нему в этом ответе. Я просто предложил несколько быстрых исправлений.

Спасибо Maarten Bodewes за то, что он привел меня к ошибке.

...