2010-07-22 13 views
34

क्या पीईएम स्वरूपित स्ट्रिंग में X509Certificate लिखने के लिए कुछ उच्च स्तरीय तरीका है? वर्तमान में मैं इसे एक डीईआर स्वरूपित स्ट्रिंग में लिखने के लिए x509cert.encode() कर रहा हूं, फिर इसे 64 एन्कोडिंग करें और पीईएम स्ट्रिंग बनाने के लिए हेडर और पाद लेख को जोड़ना, लेकिन यह बुरा लगता है। खासकर जब से मुझे लाइन ब्रेक में फेंकना पड़ता है।जावा में पीईएम स्वरूपित स्ट्रिंग में x509 प्रमाण पत्र लिखें?

उत्तर

47

यह बुरा नहीं है। जावा पीईएम फाइलों को लिखने के लिए कोई काम नहीं करता है। आप क्या कर रहे हैं सही तरीका है। यहां तक ​​कि Keytool एक ही बात करता है,

BASE64Encoder encoder = new BASE64Encoder(); 
out.println(X509Factory.BEGIN_CERT); 
encoder.encodeBuffer(cert.getEncoded(), out); 
out.println(X509Factory.END_CERT); 

आप BouncyCastle का उपयोग करते हैं, तो आप PEMWriter वर्ग पीईएम में X509 प्रमाण पत्र को लिखने के लिए उपयोग कर सकते हैं।

+4

PEMWriter अब मान्य नहीं है। JcaPEMWriter नई कक्षा है जो इसे बदल देती है। – rancidfishbreath

7

जेडजेड सांकेतिक शब्दों में बदलनेवाला के विचार पर निर्माण करने के लिए, लेकिन sun.misc कक्षाएं कि JRE संस्करणों के बीच लगातार होने की गारंटी नहीं कर रहे हैं का उपयोग किए बिना, पर विचार यह

उपयोग कक्षा:

import javax.xml.bind.DatatypeConverter; 

कोड:

try { 
    System.out.println("-----BEGIN CERTIFICATE-----"); 
    System.out.println(DatatypeConverter.printBase64Binary(x509cert.getEncoded())); 
    System.out.println("-----END CERTIFICATE-----"); 
} catch (CertificateEncodingException e) { 
    e.printStackTrace(); 
} 
+0

सूर्य का कोई भी नहीं। * कक्षाएं स्थिर होने का इरादा रखती हैं: http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html – pimlottc

+0

धन्यवाद pimlottc। मैंने sun.security.provider.X509 फैक्टरी क्षेत्र संदर्भ हटा दिए और स्ट्रिंग मानों के साथ उन्हें बदल दिया। – judoman

15

पिछला उत्तर 3de पार्टी सॉफ़्टवेयर (जैसे PHP) के साथ संगतता समस्याएं देता है, क्योंकि पीईएम प्रमाण सही ढंग से खंडित नहीं होता है।

आयात:

import org.apache.commons.codec.binary.Base64; 

कोड:

protected static String convertToPem(X509Certificate cert) throws CertificateEncodingException { 
Base64 encoder = new Base64(64); 
String cert_begin = "-----BEGIN CERTIFICATE-----\n"; 
String end_cert = "-----END CERTIFICATE-----"; 

byte[] derCert = x509cert.getEncoded(); 
String pemCertPre = new String(encoder.encode(derCert)); 
String pemCert = cert_begin + pemCertPre + end_cert; 
return pemCert; 
} 
+1

इसे ओपनएसएसएल के लिए आम तौर पर 64 वर्णों की लाइनों में होना चाहिए। – Cathy

5

आप उछाल वाले महल से PEMWriter है, तो आप कर सकते हैं निम्नलिखित:

आयात:

import org.bouncycastle.openssl.PEMWriter; 

संहिता:

/** 
* Converts a {@link X509Certificate} instance into a Base-64 encoded string (PEM format). 
* 
* @param x509Cert A X509 Certificate instance 
* @return PEM formatted String 
* @throws CertificateEncodingException 
*/ 
public String convertToBase64PEMString(Certificate x509Cert) throws IOException { 
    StringWriter sw = new StringWriter(); 
    try (PEMWriter pw = new PEMWriter(sw)) { 
     pw.writeObject(x509Cert); 
    } 
    return sw.toString(); 
} 
+0

यह ऑब्जेक्ट "pw.flush()" लिखने के बाद इसे जोड़ने के लिए इसे खाली स्ट्रिंग वापस कर देगा। – StalkAlex

10

निम्नलिखित कोई बाहरी बाह्य पुस्तकालय या संभवतः संस्करण-असंगत सूर्य का उपयोग नहीं करता है। * पुस्तकालय। यह न्यायपालिका के उत्तर पर बनाता है, लेकिन यह ओपनएसएसएल, जावा और अन्य द्वारा आवश्यक 64 वर्णों पर लाइनों को भी चुनता है।

आयात:

import javax.xml.bind.DatatypeConverter; 
import java.security.cert.X509Certificate; 
import java.io.StringWriter; 

कोड:

public static String certToString(X509Certificate cert) { 
    StringWriter sw = new StringWriter(); 
    try { 
     sw.write("-----BEGIN CERTIFICATE-----\n"); 
     sw.write(DatatypeConverter.printBase64Binary(cert.getEncoded()).replaceAll("(.{64})", "$1\n")); 
     sw.write("\n-----END CERTIFICATE-----\n"); 
    } catch (CertificateEncodingException e) { 
     e.printStackTrace(); 
    } 
    return sw.toString(); 
} 

(मैं सिर्फ judoman के उत्तर पर टिप्पणी की हैं, लेकिन मैं काफी प्रतिष्ठा अंक टिप्पणी करने के लिए अनुमति दी जा की जरूरत नहीं है, और मेरे सरल संपादन अस्वीकार कर दिया गया था क्योंकि यह एक टिप्पणी या उत्तर होना चाहिए था, तो यहां जवाब है।)

आप सीधे फाइल करने के लिए, यह भी import java.io.FileWriter और लिखने के लिए करना चाहते हैं:

FileWriter fw = new FileWriter(certFilePath); 
fw.write(certToString(myCert)); 
fw.close(); 
9

किसी को भी जावा 8 के ऊपर लाने के नहीं देखा है Base64.getMimeEncoder विधि अभी तक - वास्तव में आप दोनों लाइन की लंबाई निर्दिष्ट कर सकते हैं और इसलिए जैसे लाइन विभाजक:

final Base64.Encoder encoder = Base64.getMimeEncoder(64, LINE_SEPARATOR.getBytes()); 

मैं अगर वहाँ इस^साथ कोई अंतर बनाम मानक एनकोडर था देखने के लिए लग रहा था, और मैं कुछ भी नहीं मिला। javadoc बीएएसआईसी के लिए RFC 4648 के अतिरिक्त, बेसिक और एमआईएमई एन्कोडर्स दोनों के लिए RFC 2045 को उद्धृत करता है। AFAIK इन दोनों मानकों में एक ही बेस 64 वर्णमाला (तालिकाएं समान दिखती हैं) का उपयोग करती हैं, इसलिए यदि आपको लाइन की लंबाई निर्दिष्ट करने की आवश्यकता है तो आपको MIME का उपयोग करना ठीक होना चाहिए।

इसका मतलब यह है कि जावा 8 के साथ, इस के साथ पूरा किया जा सकता है:

import java.security.cert.Certificate; 
import java.security.cert.CertificateEncodingException; 
import java.util.Base64; 

फिर भी एक और विकल्प का उपयोग कर एन्कोड करने के लिए ...

public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----"; 
public static final String END_CERT = "-----END CERTIFICATE-----"; 
public final static String LINE_SEPARATOR = System.getProperty("line.separator"); 

...

public static String formatCrtFileContents(final Certificate certificate) throws CertificateEncodingException { 
    final Base64.Encoder encoder = Base64.getMimeEncoder(64, LINE_SEPARATOR.getBytes()); 

    final byte[] rawCrtText = certificate.getEncoded(); 
    final String encodedCertText = new String(encoder.encode(rawCrtText)); 
    final String prettified_cert = BEGIN_CERT + LINE_SEPARATOR + encodedCertText + LINE_SEPARATOR + END_CERT; 
    return prettified_cert; 
} 
+0

कॉल को एपीआई स्तर 26 की आवश्यकता है। – Pei

0

Guava's BaseEncoding:

import com.google.common.io.BaseEncoding; 

public static final String LINE_SEPARATOR = System.getProperty("line.separator"); 
public static final int LINE_LENGTH = 64; 

और फिर:

String encodedCertText = BaseEncoding.base64() 
            .withSeparator(LINE_SEPARATOR, LINE_LENGTH) 
            .encode(cert.getEncoded()); 
संबंधित मुद्दे