title: Unable to perform communication between java client and python server with SSL
body: <p>I am trying to use keys and certificate generated using java <code>keytool</code> in python server and java client. I have created key &amp; keystore, exported certificate, added certificate to truststore, converted keystore to standard pkcs format and then extracted key and certificate from pkcs to use in python server. (first three steps from <a href="https://docs.oracle.com/cd/E19830-01/819-4712/ablrb/index.html" rel="nofollow noreferrer">here</a> and last three steps from <a href="https://security.stackexchange.com/a/66865/89945">here</a>) Here are the detailed steps:</p>
  
  <ol>
  <li><p>Creating keystore, private key and certificate</p>
  
  <pre><code>keytool -genkey -alias ssl_key -keyalg RSA -keypass passwd123 -keystore keystore.jks -storepass passwd123
  </code></pre></li>
  <li><p>Exporting certificate out from keystore to <code>.cer</code> file</p>
  
  <pre><code>keytool -export -alias ssl_key -file ssl_key.cer -keystore keystore.jks -storepass passwd123
  </code></pre></li>
  <li><p>Exporting certificate from keystore to truststore</p>
  
  <pre><code>keytool -import -v -trustcacerts -alias ssl_key -keypass passwd123 -file ssl_key.cer -keystore truststore.jks -storepass passwd123
  </code></pre></li>
  <li><p>Exported keystore from keytool's proprietary format to standard format</p>
  
  <pre><code>keytool -importkeystore -srckeystore keystore.jks -destkeystore stdkeystore.p12 -deststoretype PKCS12 -srcalias ssl_key -deststorepass passwd123 -destkeypass passwd123
  </code></pre></li>
  <li><p>Exported certificate from standard format keystore using openssl</p>
  
  <pre><code>openssl pkcs12 -in stdkeystore.p12 -nokeys -out cert.pem
  </code></pre></li>
  <li><p>Exported unencrypted private key from standard format keystore using openssl as follows:  </p>
  
  <pre><code>openssl pkcs12 -in stdkeystore.p12  -nodes -nocerts -out key.pem
  </code></pre></li>
  </ol>
  
  <p>My small python server and java client are as follows:</p>
  
  <p><strong>server.py</strong></p>
  
  <pre><code>import socket
  import ssl
  
  def start_server_ssl():
  
      socketObj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      server_address = ('127.0.0.1', 6000)
      socketObj.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      socketObj.bind(server_address)
      socketObj.listen(10)
  
      while True:
          try:
              print("Awaiting connection...")
              data_socket, client_address = socketObj.accept()
              ssl_socket = ssl.wrap_socket(socketObj,
                              server_side = True,
                              certfile="cert.pem",
                              keyfile="key.pem")        
  
              reading_status = True
              data = bytearray()
              data_decoded = ""
              while(reading_status):
                  message_chunks = data_socket.recv(90000)
                  data.extend(message_chunks)
  
                  print(data)          
                  data_decoded = str(data.decode("utf-8"))
                  #data_decoded = str(data.decode())
  
                  if(data_decoded.startswith("&lt;&lt;startMessage&gt;&gt;")):
                      if(data_decoded.endswith("&lt;&lt;endMessage&gt;&gt;")):
                          reading_status = False
                          print(data_decoded);
  
          except socket.error as msg:
              print (msg)
  
      ssl_socket.shutdown(socket.SHUT_RDWR)
      ssl_socket.close()
  
  if __name__ == '__main__':
      start_server_ssl()
  </code></pre>
  
  <p><strong>Client4Py.java</strong></p>
  
  <pre><code>import java.io.BufferedWriter;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.OutputStreamWriter;
  import java.io.PrintWriter;
  import java.nio.charset.StandardCharsets;
  import java.security.KeyStore;
  
  import javax.net.ssl.KeyManagerFactory;
  import javax.net.ssl.SSLContext;
  import javax.net.ssl.SSLSocket;
  import javax.net.ssl.SSLSocketFactory;
  import javax.net.ssl.TrustManager;
  import javax.net.ssl.TrustManagerFactory;
  
  public class Client4Py {
      static KeyStore ks;
      static KeyManagerFactory kmf;
      static TrustManagerFactory tmf;
      static SSLContext sc;
      static TrustManager[] trustManagers;
  
      static {
          try {
              ks = KeyStore.getInstance("JKS");
              ks.load(new FileInputStream("D:\\javasslstores\\truststore.jks"), "passwd123".toCharArray());
  
              kmf = KeyManagerFactory.getInstance("SunX509");
              kmf.init(ks, "passwd123".toCharArray());
  
              tmf = TrustManagerFactory.getInstance("SunX509"); 
              tmf.init(ks);
  
              sc = SSLContext.getInstance("TLS"); 
  
              sc.init(null, tmf.getTrustManagers(), null);
          } catch (Exception e) {
              System.out.println(e.getMessage());
              System.out.println(e.getStackTrace());
          }
      }
  
      public static void main(String[] args) throws IOException {
          SSLSocketFactory ssf = sc.getSocketFactory();
          SSLSocket socket = (SSLSocket) ssf.createSocket("127.0.0.1", 6000);
          socket.startHandshake();
  
          PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),StandardCharsets.UTF_8)));
          //PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
  
          out.println("&lt;&lt;startMessage&gt;&gt;");
          out.println("Message from Client4Py");
          out.println("&lt;&lt;endMessage&gt;&gt;");
          out.flush();
  
          if (out.checkError())
              System.out.println(
                  "SSLSocketClient:  java.io.PrintWriter error");
  
          out.close();
          socket.close();
      }
  }
  </code></pre>
  
  <p>The output on server's console after first running server and the client is as follows:</p>
  
  <pre><code>Awaiting connection...
  bytearray(b'\x16\x03\x03\x00\xc1\x01\x00\x00\xbd\x03\x03["}o\x12\x01\xb2\xd4E\xa1\x1fy\xa8/d\x11\xd2\x00)\\t\x9a:\xb6\n\xcd\x03\x05\xbe\xe58\xd6\x00\x00:\xc0#\xc0\'\x00&lt;\xc0%\xc0)\x00g\x00@\xc0\t\xc0\x13\x00/\xc0\x04\xc0\x0e\x003\x002\xc0+\xc0/\x00\x9c\xc0-\xc01\x00\x9e\x00\xa2\xc0\x08\xc0\x12\x00\n\xc0\x03\xc0\r\x00\x16\x00\x13\x00\xff\x01\x00\x00Z\x00\n\x004\x002\x00\x17\x00\x01\x00\x03\x00\x13\x00\x15\x00\x06\x00\x07\x00\t\x00\n\x00\x18\x00\x0b\x00\x0c\x00\x19\x00\r\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x02\x00\x12\x00\x04\x00\x05\x00\x14\x00\x08\x00\x16\x00\x0b\x00\x02\x01\x00\x00\r\x00\x18\x00\x16\x06\x03\x06\x01\x05\x03\x05\x01\x04\x03\x04\x01\x03\x03\x03\x01\x02\x03\x02\x01\x02\x02')
  Traceback (most recent call last):
    File "D:\Mahesh\workspaces\workspace6\PythonServer\server.py", line 44, in &lt;module&gt;
      start_server_ssl()
    File "D:\Mahesh\workspaces\workspace6\PythonServer\server.py", line 29, in start_server_ssl
      data_decoded = str(data.decode("utf-8"))
  UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 4: invalid start byte
  </code></pre>
  
  <p>I uncommented utf-8 encoding-decoding lines in client and server code and ended up getting following output on server's console:</p>
  
  <pre><code>Awaiting connection...
  bytearray(b'\x16\x03\x03\x00\xc1\x01\x00\x00\xbd\x03\x03["\x7f&gt;s\x04\x15S\x14\xb0\xa2\xa0\x7f\x90}@\xe8\xa3:\x15\x04z\xeb\x986\\b\xe9\xe0v=\x1f\x00\x00:\xc0#\xc0\'\x00&lt;\xc0%\xc0)\x00g\x00@\xc0\t\xc0\x13\x00/\xc0\x04\xc0\x0e\x003\x002\xc0+\xc0/\x00\x9c\xc0-\xc01\x00\x9e\x00\xa2\xc0\x08\xc0\x12\x00\n\xc0\x03\xc0\r\x00\x16\x00\x13\x00\xff\x01\x00\x00Z\x00\n\x004\x002\x00\x17\x00\x01\x00\x03\x00\x13\x00\x15\x00\x06\x00\x07\x00\t\x00\n\x00\x18\x00\x0b\x00\x0c\x00\x19\x00\r\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x02\x00\x12\x00\x04\x00\x05\x00\x14\x00\x08\x00\x16\x00\x0b\x00\x02\x01\x00\x00\r\x00\x18\x00\x16\x06\x03\x06\x01\x05\x03\x05\x01\x04\x03\x04\x01\x03\x03\x03\x01\x02\x03\x02\x01\x02\x02')
  Traceback (most recent call last):
    File "D:\Mahesh\workspaces\workspace6\PythonServer\server.py", line 44, in &lt;module&gt;
      start_server_ssl()
    File "D:\Mahesh\workspaces\workspace6\PythonServer\server.py", line 30, in start_server_ssl
      data_decoded = str(data.decode())
  UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 4: invalid start byte
  </code></pre>
  
  <p>I feel I am missing something. Either some basics of SSL or encoding. Can I use pem file generated from java keystore as explained above directly with python <code>SSLSocket</code>? Or do I have to ensure something more like ciphers used to generate keys and certificate?</p>
  
  <p>Any links/resources to dispel my ignorance are welcome...</p>