一、生成證書,所需機器數必須 >= 2(一臺生成服務端證書,一臺生成客戶端證書),以下伺服器以A表示服務端、B表示客戶端來舉例,thrift版本為0.7.01、自簽名的證書的生成和測試 1)生成密鑰和證書相關 服務端A, openssl genrsa -out server-key.pem 2048
一、生成證書,所需機器數必須 >= 2(一臺生成服務端證書,一臺生成客戶端證書),以下伺服器以A表示服務端、B表示客戶端來舉例,thrift版本為0.7.0
1、自簽名的證書的生成和測試
1)生成密鑰和證書相關
服務端A,
openssl genrsa -out server-key.pem 2048
openssl req -new -x509 -key server-key.pem -out server-cert.pem -days 10000
客戶端B
openssl genrsa -out client-key.pem 2048
openssl req -new -x509 -key client-key.pem -out client-cert.pem -days 10000
由key生成keystore,crt生成truststore(針對服務端,客戶端的類似)
openssl pkcs12 -export -in server-key.pem -inkey server-key.pem -out server.pkcs12 打包伺服器端資料為pkcs12格式
keytool -importkeystore -srckeystore server.pkcs12 -destkeystore server.jks -srcstoretype pkcs12 生成keystore,使用keytool的importkeystore指令。pkcs12轉jks。需要pkcs12密碼和jks密碼。
keytool -importcert -alias servercert -file server.crt -keystore servertrust.jks 把Server證書加到對外KeyStore裡面。
2)測試
1、c++---c++ 成功
環境:linux6u3-64
A:./server 9091 self_signed_normal/server-cert.pem self_signed_normal/server-key.pem self_signed_normal/client-cert.pem
B:./client A 9091 selfsigned/client-cert.pem selfsigned/client-key.pem selfsigned/server-cert.pem
2、java---java成功
1)環境:win7
A:keystore:server.jks
B: truststore: servertrust.jks
2)環境:linu6u3-64
A:keystore:server.jks
B: truststore: servertrust.jks
3)環境:
A:linux6u3-64 keystore:server.jks
B:win7 servertrust.jks
4)環境:
A:win7
B:linux6u3-64
3、c++---java 部分成功
1)不成功:c++在A機器,java在B機器(c++做服務端,java做客戶端)
A端報的錯誤:TThreadedServer client died: SSL_accept: wrong version number
2)成功(java做服務端,c++客戶端)
環境:
A:linux6u3-64 java server.jks
B:./client A 9091 selfsigned/client-cert.pem selfsigned/client-key.pem selfsigned/server-cert.pem 、、
註意:若B運行命令行中A的IP填的不是A的IP(原始生成服務端證書的IP),則報ERROR: authorize: cannot authorize peer,原因是IP不是服務端證書的IP
所以針對c++做客戶端的情況,服務端程式必須與生成服務端證書的機器是同一臺(java做客戶端則不需要)()
結論:
1、客戶端在連接服務端時 需指定服務端IP為創建服務端證書的IP
2、c++作為服務端,java作為客戶端,都不成功(但是外網0.9.3版本的thrift,socketFactory->authenticate(false);時能夠成功,0.7.0無論如何都不行)
2、根證書頒發
1)根證書IP 192.168.137.10
openssl genrsa -out rootkey.pem 2048
openssl req -x509 -new -key rootkey.pem -out root.crt
2)客戶端IP 192.168.137.11
openssl genrsa -out clientkey.pem 2048
openssl req -new -key clientkey.pem -out client.csr
openssl x509 -req -in client.csr -CA root.crt -CAkey rootkey.pem -CAcreateserial -days 3650-out client.crt
3)服務端IP 192.168.137.12
openssl genrsa -out serverkey.pem 2048
openssl req -new -key serverkey.pem -out server.csr
openssl x509 -req -in server.csr -CA root.crt -CAkey rootkey.pem -CAcreateserial -days 3650-out server.crt
4)由key生成keystore,crt生成truststore(針對服務端,客戶端的類似,在c++和java通信時需要用到)
openssl pkcs12 -export -in server.crt -inkey serverkey.pem -out server.pkcs12 打包伺服器端資料為pkcs12格式(server.pkcs12 )。需要輸入密碼,請記住。
keytool -importkeystore -srckeystore server.pkcs12 -destkeystore server.jks -srcstoretype pkcs12 生成伺服器端keystore(server.jks)。使用keytool的importkeystore指令。pkcs12轉jks。需要pkcs12密碼和jks密碼。
keytool -importcert -alias ca -file root.crt -keystore servertrust.jks 生成Server端的對外KeyStore。先把根證書放到裡面。
keytool -importcert -alias servercert -file server.crt -keystore servertrust.jks 把Server證書加到對外KeyStore裡面。
測試
c++---c++成功
./server_normal 9091 keys/server.crt keys/server.key keys/ca.crt
./client.bak 172.16.22.22 9091 keys/client.crt keys/clientkey.pem keys/ca.crt
java---java成功(同自簽名)
c++---java
1)c++服務端,java客戶端 不成功
2)java服務端,c++客戶端 成功,但是客戶端socketFactory->loadTrustedCertificates(""ca.crt");
ssl創建加密通信代碼:
服務端:
shared_ptr<TBufferedTransportFactory> transportFactory =
shared_ptr<TBufferedTransportFactory>(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
shared_ptr<TProcessor> processor(new CalculatorProcessor(handler));
shared_ptr<TSSLSocketFactory> socketFactory =
shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
socketFactory->server(true);
socketFactory->authenticate(true);
socketFactory->loadCertificate("/home/study/openssl-ca/self_signed_normal/server.crt");
socketFactory->loadPrivateKey("/home/study/openssl-ca/self_signed_normal/server.key");
socketFactory->loadTrustedCertificates("/home/study/openssl-ca/self_signed_normal/client.crt");
socketFactory->ciphers("HIGH:!DSS:!aNULL@STRENGTH");
shared_ptr<TSSLServerSocket> socket(new TSSLServerSocket(port, socketFactory));
TThreadedServer server(processor,
socket,
transportFactory,
protocolFactory);
printf("Security server start \n");
server.serve();
客戶端
shared_ptr <TSSLSocketFactory> socketFactory = shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
socketFactory->authenticate(true);
socketFactory->loadCertificate("/home/study/openssl-ca/self_signed_normal/client.crt");
socketFactory->loadPrivateKey("/home/study/openssl-ca/self_signed_normal/client-key.pem");
socketFactory->loadTrustedCertificates("/home/study/openssl-ca/self_signed_normal/server.crt");
// socketFactory->ciphers("HIGH:!DSS:!aNULL@STRENGTH");
shared_ptr <TSSLSocket>socket = socketFactory->createSocket("localhost", 9091);
shared_ptr<TBufferedTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
CalculatorClient client(protocol);