一、生成证书,所需机器数必须 >= 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-cert.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);