keytool
在python服务器和java客户端。我已经创建了;密钥库,导出证书,将证书添加到信任库,将密钥库转换为标准pkcs格式,然后从pkcs中提取密钥和证书以在python服务器中使用(开始的前三步
here
最后三步
here
this question
有关生成密钥和证书的详细步骤,请参阅
that question
.
我的SSL服务器看起来像这样
服务器.py
import socket
import multiprocessing as mup
import ssl
def worker_ssl(data_socket, client_address):
print("Inside worker")
#some processing
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)
ssl_socket = ssl.wrap_socket(socketObj,
server_side = True,
certfile="cert.pem",
keyfile="key.pem")
while True:
print("Waiting For Connections .........\n")
try:
data_socket, client_address = ssl_socket.accept()
process = mup.Process(target=worker_ssl, args=(data_socket, client_address))
process.daemon = True
process.start()
except socket.error as msg:
print (" [ERROR] : %s " % msg)
continue
socketObj.close()
ssl_socket.shutdown(socket.SHUT_RDWR)
ssl_socket.close()
if __name__ == '__main__':
start_server_ssl()
SSL客户端如下所示:
客户端4py.java
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("<<startMessage>>");
out.println("Message from Client4Py");
out.println("<<endMessage>>");
out.flush();
if (out.checkError())
System.out.println(
"SSLSocketClient: java.io.PrintWriter error");
out.close();
socket.close();
}
}
首先运行服务器,然后运行客户端之后,服务器控制台上的输出如下:
1 Waiting For Connections .........
2
3 Traceback (most recent call last):
4 File "D:\workspaces\workspace6\PythonServer\server.py", line 40, in <module>
5 start_server_ssl()
6 File "D:\workspaces\workspace6\PythonServer\server.py", line 29, in start_server_ssl
7 process.start()
8 File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\process.py", line 105, in start
9 self._popen = self._Popen(self)
10 File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\context.py", line 223, in _Popen
11 return _default_context.get_context().Process._Popen(process_obj)
12 File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\context.py", line 322, in _Popen
13 return Popen(process_obj)
14 File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
15 reduction.dump(process_obj, to_child)
16 File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\reduction.py", line 60, in dump
17 ForkingPickler(file, protocol).dump(obj)
18 File "D:\Programs\python\python-3.6.6-amd64\lib\socket.py", line 185, in __getstate__
19 raise TypeError("Cannot serialize socket object")
20 TypeError: Cannot serialize socket object
21 Traceback (most recent call last):
22 File "<string>", line 1, in <module>
23 File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\spawn.py", line 99, in spawn_main
24 new_handle = reduction.steal_handle(parent_pid, pipe_handle)
25 File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\reduction.py", line 87, in steal_handle
26 _winapi.DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE)
27 PermissionError: [WinError 5] Access is denied
你可以在20号线上看到,有
TypeError: Cannot serialize socket object
代码在删除所有SSL内容后开始工作
当我给你打电话
wrap_socket()
,替换
ssl_socket.accept()
socketObject.accept()
和评论
ssl_socket.shutdown()
和
close()
worker()
Inside worker
在控制台上。以下是修改后的非SSL服务器:
import socket
import multiprocessing as mup
# import ssl
def worker_ssl(data_socket, client_address):
print("Inside worker")
#some processing
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)
# ssl_socket = ssl.wrap_socket(socketObj,
# server_side = True,
# certfile="cert.pem",
# keyfile="key.pem")
while True:
print("Waiting For Connections .........\n")
try:
data_socket, client_address = socketObj.accept()
process = mup.Process(target=worker_ssl, args=(data_socket, client_address))
process.daemon = True
process.start()
except socket.error as msg:
print (" [ERROR] : %s " % msg)
continue
socketObj.close()
# ssl_socket.shutdown(socket.SHUT_RDWR)
# ssl_socket.close()
if __name__ == '__main__':
start_server_ssl()