QtJava笔记-Qt与Java进行SSL双向认证(Qt客户端,Java服务端)
生活随笔
收集整理的這篇文章主要介紹了
QtJava笔记-Qt与Java进行SSL双向认证(Qt客户端,Java服务端)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
這里使用Java作為服務(wù)端,使用Qt作為客戶端。
程序運(yùn)行截圖如下:
這里的證書Qt使用的p12,Java使用的jks,看以前的博文生成。
源碼打包下載地址:
https://github.com/fengfanchen/Java/tree/master/Ssl_QtClient_JavaServer
Qt客戶端源碼:
源碼如下:
QSSLClient.h
#ifndef QSSLCLIENT_H #define QSSLCLIENT_H#include <QObject> #include <QSslError>QT_BEGIN_NAMESPACE class QSslCertificate; class QSslKey; class QSslSocket; QT_END_NAMESPACEclass QSSLClient : public QObject {Q_OBJECT public:QSSLClient(QObject *parent = nullptr);~QSSLClient();void connectServer();void sendMsg(const QString &msg);void closeSocket();Q_SIGNALS:void disconnected(void);protected:void loadCertificate();private slots:void sslErrors(const QList<QSslError> &errors);void rx(void);void serverDisconnect(void);private:QList<QSslCertificate> m_publicCertificateList;QSslCertificate *m_privateCertificate;QSslKey *m_key;QSslSocket *m_client; };#endif // QSSLCLIENT_Hmain.cpp
#include <QCoreApplication> #include <QTimer> #include <QDebug> #include "QSSLClient.h"int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QSSLClient sslClient;sslClient.connectServer();sslClient.sendMsg("Hello Server");QTimer::singleShot(2 * 1000, &sslClient, &QSSLClient::closeSocket);return a.exec(); }QSSLClient.cpp
#include "QSSLClient.h" #include <QSslSocket> #include <QSslCertificate> #include <QFile> #include <QSslKey> #include <QJsonDocument> #include <QList> #include <QDebug>QSSLClient::QSSLClient(QObject *parent) : QObject(parent) {m_key = new QSslKey;m_privateCertificate = new QSslCertificate;m_client = new QSslSocket;loadCertificate();connect(m_client, &QSslSocket::readyRead, this, &QSSLClient::rx);connect(m_client, &QSslSocket::disconnected, this, &QSSLClient::serverDisconnect);connect(m_client, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));m_client->addCaCertificates(m_publicCertificateList);m_client->setPrivateKey(*m_key);m_client->setLocalCertificate(*m_privateCertificate);m_client->setPeerVerifyMode(QSslSocket::VerifyPeer);qDebug() << "QSSLClient load over"; }QSSLClient::~QSSLClient() {delete m_privateCertificate;delete m_client;delete m_key; }void QSSLClient::connectServer() {m_client->connectToHostEncrypted("localhost", 19999);if(m_client->waitForEncrypted(5000)){qDebug() << "Authentication Suceeded";}else{qDebug("Unable to connect to server");exit(0);} }void QSSLClient::sendMsg(const QString &msg) {m_client->write(msg.toUtf8()); }void QSSLClient::closeSocket() {if(m_client->disconnect()){m_client->close();qDebug() << "close success";} }void QSSLClient::loadCertificate() {QFile p12File(":/res/p_client.p12");if(!p12File.open(QIODevice::ReadOnly)){qDebug() << "The certificate file open failed!";exit(0);}bool ok = QSslCertificate::importPkcs12(&p12File, m_key, m_privateCertificate, &m_publicCertificateList, "cccccc");if(!ok){qDebug() << "The certificate import error!";exit(0);}p12File.close(); }void QSSLClient::sslErrors(const QList<QSslError> &errors) {foreach (const QSslError &error, errors)qDebug() << error.errorString(); }void QSSLClient::rx() {QString getMsg = m_client->readAll();qDebug() << getMsg; }void QSSLClient::serverDisconnect() { // m_client->close(); // exit(0); }Java服務(wù)端源碼:
SslContextProvider.java
package cn.it1995;import javax.net.ssl.KeyManager; import javax.net.ssl.TrustManager;public interface SslContextProvider {TrustManager[] getTrustManagers() throws Exception;KeyManager[] getKeyManagers() throws Exception;String getProtocol(); }SslUtil.java
package cn.it1995;import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; import javax.net.ssl.*; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.net.Socket; import java.security.*; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException;public class SslUtil {private static final String JKS = "JKS";public static KeyManager[] createKeyManagers(String keyStorePath, String password) throws Exception {return createKeyManagers(keyStorePath, password, password);}public static KeyManager[] createKeyManagers(String keyStorePath, String storePassword, String keyPassword) throws Exception {String defaultAlgorithm = KeyManagerFactory.getDefaultAlgorithm();KeyManagerFactory kmInstance = KeyManagerFactory.getInstance(defaultAlgorithm);KeyStore ksInstance = KeyStore.getInstance(JKS);FileInputStream fileInputStream = new FileInputStream(keyStorePath);try{ksInstance.load(fileInputStream, storePassword.toCharArray());}catch (IOException e){e.printStackTrace();}catch (CertificateException e){e.printStackTrace();}finally {if(fileInputStream != null){fileInputStream.close();}}try{kmInstance.init(ksInstance, keyPassword.toCharArray());}catch (UnrecoverableKeyException e){e.printStackTrace();}return kmInstance.getKeyManagers();}public static SSLContext createSSLContext(SslContextProvider provider) throws Exception{SSLContext context = SSLContext.getInstance(provider.getProtocol());context.init(provider.getKeyManagers(), provider.getTrustManagers(), new SecureRandom());return context;}public static SSLServerSocket createSSLServerSocket(int port, SslContextProvider provider) throws Exception {SSLContext sslContext = createSSLContext(provider);SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();SSLServerSocket sslServerSocket = (SSLServerSocket)sslServerSocketFactory.createServerSocket(port);sslServerSocket.setEnabledProtocols(new String[]{provider.getProtocol()});sslServerSocket.setNeedClientAuth(true);return sslServerSocket;}public static SSLSocket createSSLSocket(String host, int port, SslContextProvider provider) throws Exception{SSLContext sslContext = createSSLContext(provider);SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(host, port);sslSocket.setEnabledProtocols(new String[]{provider.getProtocol()});return sslSocket;}public static TrustManager[] createTrustManagers(String keyStorePath, String password) throws Exception{String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();TrustManagerFactory tmInstance = TrustManagerFactory.getInstance(defaultAlgorithm);KeyStore ksInstance = KeyStore.getInstance(JKS);FileInputStream fileInputStream = new FileInputStream(keyStorePath);try{ksInstance.load(fileInputStream, password.toCharArray());}catch (IOException e){e.printStackTrace();}catch (CertificateException e){e.printStackTrace();}finally {if(fileInputStream != null){fileInputStream.close();}}tmInstance.init(ksInstance);return tmInstance.getTrustManagers();}public static String getPeerIdentity(Socket socket){if(!(socket instanceof SSLSocket)){return null;}SSLSession sslSession = ((SSLSocket)socket).getSession();try{Principal peerPrincipal = sslSession.getPeerPrincipal();return getCommonName(peerPrincipal);}catch (SSLPeerUnverifiedException e){e.printStackTrace();}return "unknown client";}private static String getCommonName(Principal subject){try{LdapName ldapName = new LdapName(subject.getName());for(Rdn rdn : ldapName.getRdns()){if("cn".equalsIgnoreCase(rdn.getType())){return (String)rdn.getValue();}}}catch (Exception e){e.printStackTrace();}return null;} }SslServer.java
package cn.it1995;import javax.net.ssl.KeyManager; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket;public class SslServer implements SslContextProvider{@Overridepublic TrustManager[] getTrustManagers() throws Exception {return SslUtil.createTrustManagers("D:\\IDEAProject\\SSLDemo\\src\\main\\resources\\server.jks", "cccccc");}@Overridepublic KeyManager[] getKeyManagers() throws Exception {return SslUtil.createKeyManagers("D:\\IDEAProject\\SSLDemo\\src\\main\\resources\\server.jks", "cccccc");}@Overridepublic String getProtocol() {return "TLSv1.2";}private ServerSocket createSSLSocket(int port) throws Exception {SSLServerSocket sslServerSocket = SslUtil.createSSLServerSocket(port, this);return sslServerSocket;}public void run(int port) throws Exception {ServerSocket serverSocket = createSSLSocket(port);System.out.println("服務(wù)端啟動(dòng)成功,等待客戶端連接 ...... ...... ...... ......");while(true){try(SSLSocket client = (SSLSocket) serverSocket.accept(); OutputStream os = client.getOutputStream(); InputStream is = client.getInputStream()){System.out.println("客戶端: " + SslUtil.getPeerIdentity(client) + " 成功連接!");byte[] b = new byte[1024];is.read(b);System.out.println("接收到客戶端消息:" + new String(b));System.out.println("發(fā)送消息給客戶端!");os.write("Hello Client".getBytes());os.flush();System.out.println("發(fā)送完成!");}catch (Exception e){e.printStackTrace();}}}public static void main(String[] args) throws Exception {new SslServer().run(19999);} }總結(jié)
以上是生活随笔為你收集整理的QtJava笔记-Qt与Java进行SSL双向认证(Qt客户端,Java服务端)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL笔记-检索出ID为Int或Long
- 下一篇: 信息安全工程师笔记-案例分析(二)