OpenSSL是什么?
概述
OpenSSL是個開源項目,為TLS和SSL提供一個健壯、商業級以及功能齊全的實現。同時,它也是個通用的加密庫。OpenSSL采用Apache-style授權,基本上可以自由應用在商業和非商業的項目上。參考1
組成
OpenSSL大概由三部分組成:
- 命令
OpenSSL中包含一個可執行程序:openssl,可以直接完成特定任務的,諸如:密鑰的生成、證書信息的查看、摘要計算以及加密解密等等。使用起來非常方便,在調試、測試的或者日常業務中可直接使用。 - SSL庫
SSL的實現 - 加密庫
加密庫,包含各種加密算法的實現、證書操作接口以及一些輔助類
其他
OpenSSL本身庫設計得比較復雜,自身問題不少,諸如之前的"heartbleed"安全漏洞,因此不少公司或者團隊都有自己的fork,諸如google的BoringSSL、OpenBSD的LibreSSL等。需要注意的是,BoringSSL在接口上不一定能兼容OpenSSL。
密碼學
概述
在使用OpenSSL,就需要對密碼學有一定的了解,這里稍微介紹一下密碼學相關的知識,便于對各種加密算法的運用。
現代密碼學,并非像很多人想象的那樣,簡單使用一個密碼加密一段文本,從而隱藏“原文”,使竊聽者不能閱讀原文。現代密碼學發展至今,功能和學科分支已經十分豐富,就基礎功能來說,主要如下:
- 機密性
如何將可理解的信息轉換成難以理解的信息,并且使得有秘密信息的人能夠逆向回復,但缺乏秘密信息的攔截者或竊聽者則無法解讀 - 鑒別
消息的接收者應該能夠確認消息的來源;入侵者不可能偽裝成他人。這點在實際應用面非常廣,諸如我們連接的服務器就是我們的服務器,而不是別人偽造的服務器。 - 報文完整性
消息的接收者應該能夠驗證在傳送過程中消息沒有被修改;入侵者不可能用假消息代替合法消息。 - 不可否認性
發送者事后不可能虛假地否認他發送的消息。
密碼學常用算法
密碼學常用的算法非常多,不同的算法應用在不同的場合當中,很多時候,也是各種算法相互配合來解決實際問題的,常見用的如下:
編譯
OpenSSL支持非常多的平臺,編譯起來也比較簡單,源碼包可以在下述網址上下載到:
以下編譯適應的源碼版本為:1.1.0b
windows下的編譯
Windows下編譯代碼,需要進行環境準備、配置以及正式編譯三個步驟,如果環境滿足條件,那么只需要后兩步就行了
準備
在windows下編譯,需要準備以下環境:
- perl
windows下的構建腳本是通過perl實現的,因此需要安裝perl運行環境:
安裝好后,可以在控制臺里面輸入:
perl --version
應該有類似字樣:
This is perl 5, version 24, subversion 0 (v5.24.0) built for MSWin32-x86-multi-thread-64int
(with 1 registered patch, see perl -V for more detail)
....
表示正確安裝了,如果提示找不到程序,說明安裝是錯誤的
- NASM
OpenSSL部分源碼使用匯編進行優化,需要安裝NASM來對相關代碼進行編譯
為了讓構建腳本找到NASM,安裝好NASM之后,需要把nasm.exe添加到PATH環境變量當中,為了驗證安裝是正確的,打開控制臺(運行->cmd回車),輸入:
nasm -version
應該有類似輸出:
NASM version 2.12.03rc1 compiled on Oct 4 2016
- Visual Studio 2013或者Visual Studio 2015
我只測試過這兩個版本,其他版本應該也是可以的
配置
在編譯前,需要配置好源碼,就是需要編譯那些功能、靜態庫還是動態庫等等
假設源碼路徑是: D:\test_openssl\openssl-1.1.0b 而 輸出的路徑是: D:\test_openssl\out
在開始菜單中按如下路徑找到:
Visual Studio 2015\Visual Studio Tools\Windows Desktop Command Prompts
VS2015 x86 Native Tools Command Prompt,點擊打開一個編譯控制臺,這個控制臺是設定好相關的環境變量的,可以調用到VS2015相關的工具鏈。
進入:D:\test_openssl\out這個目錄,執行如下命令:
perl D:\test_openssl\openssl-1.1.0b\Configure VC-WIN32
該命令會對源碼進行配置,并輸出編譯參數.
OpenSSL配置命令大概如下形式:
perl 源碼目錄\Configure 目標 配置參數
其中,如果是針對windows,那么目標又有如下四個:
VC-WIN32 | VC-WIN64A | VC-WIN64I | VC-CE
常用的參數:
- --debug
附帶調試符號 - no-asm
不適用匯編代碼,如果沒有NASM,那么可以使用該參數來跳過 - no-shared
編譯成靜態庫,默認是動態庫
其他具體的參數, 可以閱讀源碼目錄下的:INSTALL文件
編譯
配置好后,通過執行如下命令編譯:
nmake
當編譯結束后,out目錄會輸出相關的二進制文件、庫文件等等
注意:執行nmake的時候,需要從剛才打開的控制臺上進行,否則會提示nmake找不到
為了驗證編譯出來的程序是否有問題,這個時候需要編譯和執行測試用例:
nmake test
該命令會編譯并執行測試用例,輸出各個測試用例執行的情況,通過的測試用例,應該提示:ok 字樣,未啟用的功能會:skip,最后結束會出現:
All tests successful.
Files=86, Tests=422, 67 wallclock secs ( 0.39 usr + 0.13 sys = 0.52 CPU)
Result: PASS
如果提示錯誤,得進行問題分析了。
編譯出來的結果如下:
- openssl命令
在app目錄下 - 相關的dll
在out目錄下,app目錄下也有一份,主要提供給openssl命令使用 - 相關的lib和def
在windows下開發,如果是動態庫,需要lib和def文件,都在out目錄下
一般情況下,可以使用:
nmake install
進行安裝,實際就是復制相關文件到特定的安裝目錄下,默認是:C:/Program Files (x86)/OpenSSL
Hello World
為了驗證一下編譯出來的結果,我們新建一個C++項目來驗證一下。打開Visual Studio,新建一個控制臺項目,然后在項目屬性中的 【VC++Directories】:
- Include Directories
包含目錄,把OpenSSL頭文件所在的路徑添加進入,按照之前的路徑設定,就是:
D:\test_openssl\out\include
D:\test_openssl\openssl-1.1.0b\include
- Library Directories
庫文件所在的目錄,把OpenSSL編譯產生的lib文件的路徑添加進去,按照之前的設定,就是:
D:\test_openssl\out
另外還需要指定鏈接的庫,在項目屬性對話框 【Linker->Input->Additional Dependencies】 中添加:
libcrypto.lib
最后,在main函數中打印OpenSSL的版本號:
cout << "openssl version: " << OpenSSL_version(OPENSSL_VERSION) << endl;
編譯,運行,如果提示找不到dll文件,那么請把 out目錄中的libcrypto-1_1.dll復制到程序目錄下,正常輸出應該如下:
openssl version: OpenSSL 1.1.0b 26 Sep 2016
相關源碼,詳見github: https://github.com/summer2186/openssl_tutorial/tree/master/01_hello_world
linux下編譯
linux下編譯的方法和windows下編譯很類型,另外源碼目錄下:./config本身是個shell腳本,可以自動配置源碼。