2010-08-02 4 views
0

Мне нужно отправить сертификат v3 с сервера клиенту, используя сокет. Для этого: стороне сервера, я создаю сертификат, который я кодирую с base64.encode, а затем отправляю его клиенту. на стороне клиента, я получаю строку, которая содержит сертификат,Java - Отправка сертификата через сокет

Серверный код:

X509Certificate certificate = ...; 
sendAnswer(new String(certificate.getEncoded())); 

public static void sendAnswer(String ans) { 
    try { 
     s.shutdownInput(); 
     PrintWriter output = new PrintWriter(s.getOutputStream(), true); 
     output.println(new String(Base64.encode(ans.getBytes()))); 
     output.close(); 

    } catch (IOException ex) { 
     Logger.getLogger(serverThread.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

Клиентский код

String value = sendMessage(..);//method which receive the certificate from the server 

InputStream inStream = null; 
X509Certificate cert=null; 
inStream = new ByteArrayInputStream(value.getBytes()); 
CertificateFactory cf = CertificateFactory.getInstance("X.509","BC"); 
cert = (X509Certificate)cf.generateCertificate(inStream); 

public static String sendMessage(String url, int port, String tag, byte[] mex1) { 

    Socket link; 
    String reply = ""; 

    byte[] replyDec = null; 

     link = new Socket(InetAddress.getByName(url), port); 
     InputStream i = null; 
     try { 
      i = link.getInputStream(); 
     } catch (IOException ex) { 
      Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     Scanner input = new Scanner(i); 

     while (input.hasNextLine()) { 
      reply += input.nextLine(); 
     } 
     replyDec = Base64.decode(reply); 
     input.close(); 
     link.close(); 


    return new String(replyDec); 
} 

Почти все работает, на стороне клиента, если я напечатать строку я получить я получаю текст, который содержит дополнительный символ и данные сертификата. Но это создает ошибку при создании сертификата на стороне клиента. Это ошибка:

java.security.cert.CertificateException: java.io.IOException: DER length more than 4 bytes: 111 at org.bouncycastle.jce.provider.JDKX509CertificateFactory.engineGenerateCertificate(Unknown Source) at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:322)

и это линия, от которой она исходит от

cert = (X509Certificate) cf.generateCertificate(inStream); 

Любой может мне помочь?

Заранее спасибо

+0

Ваше использование струн совершенно неверно. Сертификаты представляют собой массивы байтов, а массивы байтов не могут быть правильно сохранены в String. –

ответ

2

Бросьте все это прочь и использовать SSL, который уже делает все это.

0

Возможно, ваша проблема связана с использованием PrintWriter для отправки и, возможно, что-то другое для чтения (сканера). Вы можете попробовать использовать StringWriter и StringReader, чтобы иметь соответствие с обоих концов, а затем вы можете отлаживать, если то, что вы отправляете, идеально подходит для того, что вы получаете.

1

Вы можете отправить сертификат через гнездо потоком байтов:

в стороне отправителя после конфигурации сокета:

ObjectOutputStream toServer; 
toServer = new ObjectOutputStream(socket.getOutputStream()); 
byte[] frame = theCertificate.getEncoded(); 
toServer.writeObject(frame); 

в приемной стороне после конфигурации розетки:

ObjectInputStream fromClient; 
fromClient = new ObjectInputStream(socket.getInputStream()); 
byte[] cert = fromClient.readObject(); 
java.security.cert.Certificate jsCert = CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(cert)); 

теперь вы можете использовать этот сертификат. например, при получении открытого ключа:

PublicKey thepublicKey = jsCert.getPublicKey();