web-dev-qa-db-ja.com

Java-Base64でエンコードされた証明書をデコードする方法

以下は私の要件です:

  1. プログラムには、3つのタグが付いたxmlファイルが入力として含まれます。これらのデータはすべてBase64でエンコードされています。注:プログラムはBC jarを使用しています
  2. プログラムはそれらをデコードし、署名と証明書を使用してデータが本物であることを確認する必要があります
  3. 検証済みのデータは、Base64でデコードして別のファイルに書き込む必要があります

以下は、証明書をデコードしようとする私のコードです:

_public void executeTask(InputStream arg0, OutputStream arg1) throws SomeException{
try{
    BufferedReader br = null;
    br = new BufferedReader(new InputStreamReader(arg0));
    String orgContent  = "", splitData = "", signContent = "", certContent = "";

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
    Document doc = docBuilder.parse(arg0);
    doc.getDocumentElement().normalize();

    NodeList originalContent = doc.getElementsByTagName("OrgContent");
    Element originalElement = (Element)originalContent.item(0);
    NodeList textOrgContent = originalElement.getChildNodes();
    orgContent = ((Node)textOrgContent.item(0)).getNodeValue().trim();

    NodeList signature = doc.getElementsByTagName("Signature");
    Element signatureElement = (Element)signature.item(0);
    NodeList signatureContent = signatureElement.getChildNodes();
    signContent = ((Node)signatureContent.item(0)).getNodeValue().trim();

    NodeList certificate = doc.getElementsByTagName("Certificate");
    Element certificateElement = (Element)certificate.item(0);
    NodeList certificateContent = certificateElement.getChildNodes();
    certContent = ((Node)certificateContent.item(0)).getNodeValue().trim();
    String decodedCertContent = new String(Base64.decode(certContent),StandardCharsets.UTF_8);
    byte[] certByteValue = Base64.decode(certContent);
    CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
    System.out.println("certContent:\n" + new String(certByteValue,StandardCharsets.UTF_8));
    InputStream inputStream = new ByteArrayInputStream(Base64.decode(certContent));

    X509Certificate cert = (X509Certificate)certFactory.generateCertificate(inputStream);

    arg1.write(decodedOrgData.getBytes());
    arg1.flush();   
}
catch (ParserConfigurationException e){
    e.printStackTrace();
}
catch (IOException e){
    e.printStackTrace();
}
catch (org.xml.sax.SAXException e){
    e.printStackTrace();
}
catch (CertificateException e){
    e.printStackTrace();
}
_

}

New String(certByteValue、StandardCharsets.UTF_8)の値を出力すると、プログラムが認識できないテキストを出力します。コードの最後の行を実行すると、X509Certificate cert = (X509Certificate)certFactory.generateCertificate(inputStream);システムがJava.security.cert.CertificateExceptionをスローします:証明書を解析できませんでした:Java.io.IOException:無効なBER/DERデータ(巨大すぎる?)。

私はこれらの証明書の初心者なので、行き詰まりを経験しています。要件に進むことができません。上記の要件を達成する方法を教えてください。

編集上記のコードへの入力ストリームはxmlファイルになります。別のプログラムは、署名と証明書を含むbase64エンコードされたデータでそのxmlファイルを作成します。そのプログラムでは、証明書をエンコードするために以下のコードが使用されます:

_        KeyStore keyStore = KeyStore.getInstance("JKS");
    keyStore.load(new FileInputStream("Filepath/certificate.p12"), "password".toCharArray());
    PrivateKey privateKey = (PrivateKey)keyStore.getKey(alias, "password".toCharArray());

        CertificateFactory factory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) factory.generateCertificate(new FileInputStream("D:/Sujai/Implementation Team/PI/Axis Treds/Certificates/PI_7.5_Cert/Arteria_Certificate-cert.cert"));
    byte[] encodedCert = certificate.getEncoded();
    String encodedStringCert = new String(Base64.encode(new String(encodedCert).getBytes(StandardCharsets.UTF_8)));
_

変数encodedStringCertは、タグ内の証明書値として渡されます。この質問の冒頭で共有したプログラムで、この証明書の値をデコードする必要があります。

証明書の内容の例:----- BEGIN CERTIFICATE ----- MIIDBjCCAe6 .... IM1g == ----- END CERTIFICATE -----

7
Sujaikareik

new String(certByteValue,StandardCharsets.UTF_8)は、証明書でエンコードされたデータが文字列として表現できないため失敗します

問題は、ソースデータがbase64 X509証明書ではないか、ライブラリBase64.decode()のエンコードの問題である可能性があります。 Java> 6の場合、Java 8 Base64.getDecoder().decode()またはDataTypeConverter.parseBase64Binary()の標準デコーダーを使用することをお勧めします

Base64でエンコードされた証明書をデコードするには、この作業コードも確認してください

String certB64 = "MIIHFDCCBfygAwIBAgIIK2o4sL7KHQgwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTYxMjE1MTQwNDE1WhcNMTcwMzA5MTMzNTAwWjBmMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEVMBMGA1UEAwwMKi5nb29nbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG1y99TYpFSSiawnjJKYI8hyEzJ4M+IELfLjmSsYI7fW/V8AT61quCswtBMikJYqzYBZrV2Reu5sHlLr6936cR6OCBKwwggSoMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjCCA2sGA1UdEQSCA2IwggNeggwqLmdvb2dsZS5jb22CDSouYW5kcm9pZC5jb22CFiouYXBwZW5naW5lLmdvb2dsZS5jb22CEiouY2xvdWQuZ29vZ2xlLmNvbYIWKi5nb29nbGUtYW5hbHl0aWNzLmNvbYILKi5nb29nbGUuY2GCCyouZ29vZ2xlLmNsgg4qLmdvb2dsZS5jby5pboIOKi5nb29nbGUuY28uanCCDiouZ29vZ2xlLmNvLnVrgg8qLmdvb2dsZS5jb20uYXKCDyouZ29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJygg8qLmdvb2dsZS5jb20uY2+CDyouZ29vZ2xlLmNvbS5teIIPKi5nb29nbGUuY29tLnRygg8qLmdvb2dsZS5jb20udm6CCyouZ29vZ2xlLmRlggsqLmdvb2dsZS5lc4ILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmh1ggsqLmdvb2dsZS5pdIILKi5nb29nbGUubmyCCyouZ29vZ2xlLnBsggsqLmdvb2dsZS5wdIISKi5nb29nbGVhZGFwaXMuY29tgg8qLmdvb2dsZWFwaXMuY26CFCouZ29vZ2xlY29tbWVyY2UuY29tghEqLmdvb2dsZXZpZGVvLmNvbYIMKi5nc3RhdGljLmNugg0qLmdzdGF0aWMuY29tggoqLmd2dDEuY29tggoqLmd2dDIuY29tghQqLm1ldHJpYy5nc3RhdGljLmNvbYIMKi51cmNoaW4uY29tghAqLnVybC5nb29nbGUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tgg0qLnlvdXR1YmUuY29tghYqLnlvdXR1YmVlZHVjYXRpb24uY29tggsqLnl0aW1nLmNvbYIaYW5kcm9pZC5jbGllbnRzLmdvb2dsZS5jb22CC2FuZHJvaWQuY29tghtkZXZlbG9wZXIuYW5kcm9pZC5nb29nbGUuY26CBGcuY2+CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5jb22CCmdvb2dsZS5jb22CEmdvb2dsZWNvbW1lcmNlLmNvbYIKdXJjaGluLmNvbYIKd3d3Lmdvby5nbIIIeW91dHUuYmWCC3lvdXR1YmUuY29tghR5b3V0dWJlZWR1Y2F0aW9uLmNvbTALBgNVHQ8EBAMCB4AwaAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBThPf/3oDfxFM/hdOi5kLv8qrZbsjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMCEGA1UdIAQaMBgwDAYKKwYBBAHWeQIFATAIBgZngQwBAgIwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3BraS5nb29nbGUuY29tL0dJQUcyLmNybDANBgkqhkiG9w0BAQsFAAOCAQEAWZQy0Kvn9cPnIh7Z4kfUCXX/dhdvjLJYFAn3b3d5DVs1BLYuukfIjilVdAeTUHZH7TLn/uVejg3yS0ssRg1ds1iv2O9DJbnl5FHcjNAvwfN533FulWP41OC6B6dC6BGGTXTvQobDup7/EKg1GWX9ksBtTfKLH5wrjhN955Itnd25Sjw2bSjLaWEtTrjINXmnBoc2+qHFzF/fNxK1KbmkBboUIGoaGsThe3AF0Ye+XAeaZH08+GdrorknlHDQLLtHIcJ3C6PrQ/kTpwWd/TVXW42BN+N7xZiGJbvKOg0S0rk2hzhgX4QoUKZHMqqh1sS6ypkfnWx75nh325y4Tenk+A==";
byte encodedCert[] = Base64.getDecoder().decode(certB64);
ByteArrayInputStream inputStream  =  new ByteArrayInputStream(encodedCert);

CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(inputStream);

証明書に----- BEGIN CERTIFICATE ---------- END CERTIFICATE -----のタグがないと思います

[〜#〜]編集済み[〜#〜]

Base_64 PEMでエンコードされた.cerファイルを直接ロードできます(-----BEGIN CERTIFICATE-----タグを使用)。

FileInputStream inputStream  =  new FileInputStream (pathToYourCert);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(inputStream);
13
pedrofb