基於openssl的計算機安全學demo(包含Diffie-Hellman,HAMC,AES的簡單應用)

       本demo主要是openssl中Diffie-Hellman,HAMC,AES的簡單應用,謹供參考(文章最後有demo的下載)。

首先,demo的大概情況:

    ·openssl版本爲openssl-1.0.1g-32bit-debug-vs2013(IDE是vs2013)

    ·使用MFC對話框的CAsyncsocket進行簡單交互

    ·主要流程:

     1)密鑰協商。Client發起密鑰協商請求,Server相應請求,並完成一次DH密鑰交換過程。
     2)身份認證。Server放提出認證請求,Client用協商出來的密鑰對一個口令作用產生一個MAC發送給Server,Server根據口令進行認證。
     3)報文發送。有一個文本輸入窗,輸入要通信的明文。按“發送”則報文明文發送;按“加密發送”按鈕則加密併發送到對方。接收方收到密文,點擊按鈕可以解密;如果收到的是普通報文則直接顯示在文本框。


流程圖:




主要代碼結構:



SCSocket                ------------------------------  服務端socket

SCClientSocket       -------------------------------客戶端socket

SCHandler              -------------------------------下面三個類的父類

SCDHHandler         -------------------------------Diffie-Hellman相關的操作(生成參數,選取祕鑰,計算共享密鑰)都在此類中

SCHMACHandler   -------------------------------生成HMAC消息認證碼

SCAESHandler       ------------------------------- AES加密

XXXDlg                   -------------------------------顯然負責界面


有關CASyncsocket的使用可參考: 一個CAsyncSocket例子

當socket收到消息,統一調用:

void SCClientSocket::OnReceive(int nErrorCode)
{
<span style="white-space:pre">	</span>// TODO: Add your specialized code here and/or call the base class
<span style="white-space:pre">	</span>pDlg->OnRecv(this);
<span style="white-space:pre">	</span>CAsyncSocket::OnReceive(nErrorCode);
}



pDlg->OnRecv :

void CSecureChatServerDlg::OnRecv(SCClientSocket * pConn)
{
	if (NULL != pConn)
	{
		char rcvBuf[513] = { 0 };
		int nRcved = 0;
		nRcved = pConn->Receive(rcvBuf, 512);
		
		if (SOCKET_ERROR != nRcved)
		{
			clientSocket->handler->processMessageFromConnection(rcvBuf, clientSocket);
		}
		
	}
}

不管收到什麼信息,都是調用 clientSocket->handler->processMessageFromConnection(rcvBuf, clientSocket);

SCClientSocket定義如下:

class SCClientSocket : public CAsyncSocket
{
public:
	SCClientSocket();
	virtual ~SCClientSocket();
	virtual void OnConnect(int nErrorCode);
	virtual void OnClose(int nErrorCode);
	virtual void OnReceive(int nErrorCode);
	void send(unsigned char * data);
	CSecureChatServerDlg * pDlg;
	SCHandler * handler;
};


SCHandler中定義了兩個虛函數:

	virtual void processMessageFromConnection(char * data, SCClientSocket *conn)
	{
		// should never call me!
	}

	virtual void start(SCClientSocket *conn,int flag)
	{
		// should never call me!
	}

保存了SCHandler * handler 指針,隨着交互流程的推進,handler可以依次指向SCDHHandler,SCHMACHandler,SCAESHandler的實例(通過調用void start(SCClientSocket *conn,int flag)改變handler所指的對象)。SCHandler的子類覆蓋了上面兩個虛函數,因此會調用各自的 void processMessageFromConnection(char * data, SCClientSocket *conn) 處理各自的消息。

爲了標識當前的交互狀態,在每個消息前面插入一個字節標記當前消息的內容:

例如SCDHHandler的processMessageFromConnection函數內容如下:

void SCDHHandler::processMessageFromConnection(char * data, SCClientSocket *conn)
{
	char DHType = data[0];

	switch ((int)DHType)
	{
	case RECV_A:  // 收到DH參數a(即本原根)
	{
	    ......
		break;
	}
	case RECV_Q:  // 收到DH參數q (大整數)
	{
	    ......
		break;
	}
	case RECV_Q_RESPON:  // 對方收到q發回的迴應
	{
	    ......
		break;

	}
	case RECV_SERVER_PUBLIC_KEY:  // 收到服務器的公開量,只會在客戶端程序觸發
	{
	    ......
		break;
	}
	case RECV_CLIENT_PUBLIC_KEY:  // 收到客戶端的公開量,只會在服務器程序觸發
	{
	    ......
		break;
	}
	default:
		AfxMessageBox(_T("diffie hellman error occur"));
		break;

	}
}

SCHMACHandler 和 SCAESHandler的代碼結構也是如上所示。

具體代碼可查看:demo下載


參考:

另外,openssl的庫是直接用別人編譯好的(自己編了幾次都失敗了):

http://p-nand-q.com/programming/windows/building_openssl_with_visual_studio_2013.html

aes例子:

https://github.com/rockyxshen/block_cipher/blob/master/aescipher.c







  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章