PDA

View Full Version : [java] convertire certificato .pem in .der


altropinto
16-03-2008, 08:59
Salve a tutti,
devo implementare una classe JAVA che effettua la conversione di un certificato (in formato .pem) in formato. der.

Quali librerie devo utilizzare?????
C'è un modo per farlo?


grazie
:muro:

altropinto
17-03-2008, 09:18
nessuna idea??????

kingv
17-03-2008, 14:57
i contenuti dei due formati sono identici, devi solo rimuovere la riga dell'intestazione (BEGIN CERTIFICATE), quella finale (END CERTIFICATE) e convertire il resto da Base64 a binario.

quando ho tempo guardo l'altra domanda.

altropinto
17-03-2008, 16:56
hai qualche esempio????
Quale classe devo utilizzare??
perchè ho provato ma non ci sono riuscito......

ti ringrazio ancora

kingv
17-03-2008, 21:18
BufferedReader input = new BufferedReader(new FileReader("test.pem"));
try
{
String line = null;
StringBuffer buf = new StringBuffer();
while (( line = input.readLine()) != null)
if (! line.startsWith("-"))
buf.append(line);
input.close();
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(buf.toString());
//dec contiene il DER
}
catch(...)

ad occhio dovrebbe andare, sistemalo tu ;)

altropinto
18-03-2008, 09:40
prima di tutto ti ringrazio per la tua disponibilità.
Ho fatto come hai detto tu:

String certfile = "D:\\usercert.pem";

BufferedReader input = new BufferedReader(new FileReader(certfile));
try
{
String line = null;
StringBuffer buf = new StringBuffer();
while ((line = input.readLine()) != null)
{
if (!line.startsWith("-"))
{
buf.append(line);
}
}
input.close();
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(buf.toString());
//dec contiene il DER

//Scrivo il certificato .der in un file

ByteArrayInputStream ba = new ByteArrayInputStream(dec);
FileOutputStream fos = new FileOutputStream(new File("D:\\usercert.der"));
int n = 0;
while ((n = ba.read()) >= 0)
{
fos.write(dec, 0, n);
}
fos.close();
ba.close();

}
catch (Exception e)
{
e.printStackTrace();
}


però c'è un problema: quando utilizzo questo certificato per creare un keystore mi solleva la seguente eccezione:
______________________________________________________________
java.security.cert.CertificateException: java.io.IOException: DerInputStream.getLength(): lengthTag=40, too big.
at sun.security.provider.X509Factory.engineGenerateCertificates(X509Factory.java:419)
_______________________________________________________________

Sembra come se la conversione non è stata eseguita correttamente.
Infatti se converto il certificato .pem con il comando openssl, non si verifica lo stesso errore:

openssl x509 -in usercert.pem -inform PEM -out usercert.der -outform DER

Inoltre il certificato convertito con il comando openssl è grande: 1.119 byte mentre quello convertito con la classe java è grande:157.938 byte.

Mi sapresti dire il motivo??????
Secondo te sbaglio nella scrittura su file????
Ti ringrazio ancora

kingv
18-03-2008, 11:02
penso che sbagli la scrittura su file, anche se non riesco a testare il tuo codice, prova con:

FileOutputStream fos = new FileOutputStream("file.der");
fos.write(dec);
fos.close();


fammi sapere.
quando posso guardo anche l'altro topic

altropinto
18-03-2008, 11:35
Adesso il certificato è grande: 1.306 byte.
Però si verifica lo stesso problema:

java.security.cert.CertificateException: java.io.IOException: DerInputStream.getLength(): lengthTag=40, too big.
at sun.security.provider.X509Factory.engineGenerateCertificates(X509Factory.java:419)

Quindi penso che non dipende dalla scrittura ma dalla decodifica effettuata.
Forse Openssl utilizza una codifica differente.

Secondo te dov'è il problema?

ti ringrazio ancora

kingv
18-03-2008, 13:22
ho creato un programmino di test e mi funziona, openssl è in grado di leggere il DER creato.
puoi postare il PEM del tuo certificato?

altropinto
19-03-2008, 11:04
per ragioni di sicurezza non te lo posso inviare in quanto il certificato non è mio.

quello che posso fare è inviarti la classe dove si verifica il problema.

Dimenticavo....mi sono accorto che la conversione da pem a der funziona con alcuni certificati ma non con quello che devo utilizzare io.
Da cosa può dipendere????Codifiche differenti?????

Allora nel file (in allegato) prova2.txt è contenuta la classe di conversione da pem a der.

Nel file ImportKey.txt invece è contenuta la classe che crea un keystore a partire dal certificato e dalla chiave privata. In questa classe si verifica l'eccezione.


Ti ringrazio ancora

kingv
19-03-2008, 12:47
beh un certificato è pubblico per cui non ci vedevo un gran problema ;)

in ogni caso con un mio PEM di test, anche la tua classe prova2 funziona correttamente :boh:

altropinto
19-03-2008, 16:28
Nel file ImportKey.txt che ti ho allegato è presente la classe che crea il keystore a partire dal certificato e dalla chiave privata. Il pezzetto di codice che ti ho riportato contiene i metodi per ricavare e caricare il certificato in formato .der nel keystore.

La mia domanda è: c'è un modo (senza effettuare la conversione da .pem a .der) per fare la stessa cosa con un certificato .pem????

// loading CertificateChain

CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream certstream = fullStream(certfile);

Collection c = cf.generateCertificates(certstream);

Certificate[] certs = new Certificate[c.toArray().length];

if (c.size() == 1)
{
certstream = fullStream(certfile);
System.out.println("One certificate, no chain.");
Certificate cert = cf.generateCertificate(certstream);
certs[0] = cert;
}
else
{
System.out.println("Certificate chain length: " + c.size());
certs = (Certificate[]) c.toArray();
}


Inoltre vorrei chiederti se hai dato un'occhiata al secondo post.

Ti ringrazio

kingv
20-03-2008, 13:29
che io sappia no.
il tuo codice mi sembra giusto, se riesci a produrre un certificato che presenta il problema e non hai vincoli a girarmi fammelo sapere.
io su un paio di test che ho fatto non ho trovato problemi.

ciao