基於openEuler的OpenSSL編譯安裝和編程基礎


基於openEuler的OpenSSL編譯安裝和編程基礎

有關OpenSSL的編譯、安裝、使用、編程我寫過一篇博客Linux下OpenSSL的安裝與使用.

由於學校跟華為合作“智能基座”產教融合協同育人基地項目,我們把學習平台從原來的X64+Ubuntu的架構換成ARM64(鯤鵬)+openEuler的架構。

ARM64 + openEuler環境可以在華為雲購買ECS,同學們使用優惠券注意按下圖選項購買:

特別提醒:做完實驗一定要關機,否則優惠券會很快用完!!!

另外還可以自己購買個樹莓派,自己安裝openEuler,可以參考這個教程樹莓派openEuler安裝.

下面演示基於華為雲ECS,鯤鵬+openEuler架構。

遠程登錄openEuler,我們看一下openEuler默認有沒有安裝OpenSSL,如下圖所示,openEuler默認已經安裝好了OpenSSL:

當前openEuler系統安裝的OpenSSL版本是1.1.1d,現在(2021.04)OpenSSL最新的版本是1.1.1k,還有一個問題,openEuler中沒有變成開發需要的頭文件。我們需要自己下載OpenSSL的源碼編譯安裝。

OpenSSL編譯安裝

  1. 我們去OpenSSL官網下載最新版本OpenSSL 1.1.1k的源碼openssl-1.1.1k.tar.gz,然后把代碼上傳到openEuler雲服務器中。
  2. 建立兩個文件夾,分別放置OpenSSL的源碼和安裝路徑,記住pwd運行的結果/root/rocopenssl
mkdir rocopensslsrc rocopenssl
cd rocopenssl
pwd 
  1. 解壓源代碼到rocopensslsrc文件夾:
tar -zxvf openssl-1.1.1k.tar.gz -C rocopensslsrc
  1. 配置編譯安裝路徑(/root/rocopenssl),和openEuler系統默認的不同。
cd rocopensslsrc/openssl-1.1.1k
./config --prefix=/root/rocopenssl
  1. 編譯(make時間稍長,耐心等待),測試、安裝,其中測試步驟可選:
make
make test
make install
  1. 查看安裝后的版本,確定是最新安裝的1.1.1k版:
cd ~/rocopenssl
./bin/openssl version

注意用到的庫還是舊版本的,這個問題怎么解決留作思考題吧

  1. 大家要注意的是rocopenssl下的include和lib的路徑,我們后面編程要用到。
/root/rocopenssl/include
/root/rocopenssl/lib

以上步驟可以使用下面的installopenssl.sh腳本完成:

#! /bin/sh

cd

if [ ! -d rocopenssl ];
then
    mkdir rocopenssl
    mkdir rocopensslsrc
fi

if [ ! -f ~/openssl-1.1.1k.tar.gz ]; 
then
	wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz
	tar -zxvf ~/openssl-1.1.1k.tar.gz -C ~/rocopensslsrc
	
	cd ~/rocopensslsrc/openssl-1.1.1k
	./config --prefix=/root/rocopenssl
	make
    make test
    make install
	
	~/rocopenssl/bin/openssl version
fi

OpenSSL命令的使用

學會工具第一招,學會查看幫助文檔,OpenSSL命令的幫助使用openssl help查看:

OpenSSL命令下面有很多子命令分為三類:標准命令,消息摘要命令和密碼命令。這些命令我們有兩種用法,以最簡單的產看版本命令為例,我們可以先輸入openssl進入OpenSSL的功能界面后輸入version,也可以直接在openEuler終端中直接輸入openssl version進行查看,在實際應用中我們多采用后一種方法。

對於子命令的使用幫助,我們可以有兩種方式查看openssl help xxsubcmdopenssl xxsubcmd --help,比如用這兩種方法查看消息摘要子命令的用法:

openssl dgst 常用選項(options)有:

[-md5|-md4|-md2|-sha1|-sha|-mdc2|-ripemd160|-dss1] :指定一種摘要算法

-out filename:將摘要值保存到指定文件中

比如我們用國密算法sm3計算besti的摘要,注意子命令的兩種用法以及管道的用法:

besti放到besti.txt文件中,計算文件的摘要:

如何使用隨機數產生對稱加密算法的密鑰?如何使用國密算法sm4進行對稱加解密?如果產生sm2的公私鑰對?如果用SM2算法加密解密,簽名驗簽?這些作為思考題吧。

OpenSSL編程

密碼算法庫的功能非常強大,是OpenSSL的基礎,它實現了現代密碼學大部分主流的密碼算法和標准,主要包括公開密鑰(非對稱)算法、對稱加密算法、信息摘要算法、X509 數字證書標准、PKCS12個人信息交換語法標准、PKCS7 加密消息語法標准、OCSP 在線證書狀態查詢協議、 CRL 證書吊銷列表等標准。同時 OpenSSL 還提供了Engine 機制;利用 Engine 可以將加密卡、加密機這樣的外部硬件算法模塊無縫集成到 OpenSSL 中。密碼算法庫在 Windows 下編譯后其庫文件為 libeay32.lib(如果編譯成動態庫則為 libeay32.dll),在 Linux 編譯后其庫文件名稱為 libcrypto.a。

現在的版本支持國密算法如SM2,SM3,SM4等算法。

簡單測試

編寫一個測試代碼test_openssl.c:

#include <stdio.h>
#include <openssl/evp.h>

int main(){
	
    OpenSSL_add_all_algorithms();
	
    return 0;
}

然后用下面命令編譯:

gcc -o to test_openssl.c -I /root/rocopenssl/include -L /root/rocopenssl/lib -lcrypto -lpthread

執行./to;echo $?,結果打印0.

BASE64算法

OpenSS1在 Evp.h中提供了Base64 編碼和解碼的函數。Base64 編碼就是把二進制數據轉換為可見的 ASCIⅡ字符。Base64 解碼是相反的過程。Base64編碼后的數據方便在 Web 中傳輸以及可視化的復制和粘貼。

OpenSSL 進行 Base64 編碼的函數主要有EVP_EncodeInit、EVP_EncodeUpdate、EVP_EncodeFinal和 EVP_EncodeBlock。其中 EVP_EncodeInit、EVP_EncodeUpdateEVP_EncodeFinal 適用於處理不定長的大數據,EVP_EncodeBlock 適用於處理短數據。

OpenSSL 進行 Base64 解碼的函數主要有EVP_Decodelnit、EVP_DecodeUpdate、EVP_DecodeFinal和 EVP_DecodeBlock。其中 EVP_DecodeInit、EVP_DecodeUpdateEVP_DecodeFinal適用於處理不定長的大數據,EVP_DecodeBlock 適用於處理短數據。

上面的函數可以完成消息的編碼和解碼,它們均定義在 openssl/evp.h 文件中。

我們要注意的是XXXInit,XXXUpdte,XXXFinal的編程模式。

我們寫一個BASE64的測試代碼testbase64.c :

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/x509.h>

//Base64編碼
void tEVP_Encode()
{
	EVP_ENCODE_CTX *ctx;
        ctx = EVP_ENCODE_CTX_new();	//EVP編碼結構體
	unsigned char in[1024];			//輸入數據緩沖區
	int inl;						//輸入數據長度
	char out[2048]={0};				//輸出數據緩沖區
	int outl;						//輸出數據長度
	FILE *infp;						//輸入文件句柄
	FILE *outfp;					//輸出文件句柄

	infp = fopen("test.dat","rb");//打開待編碼的文件
	if(infp == NULL)
	{
		printf("Open File \"Test.dat\"  for Read Err.\n");
		return;
	}
	
	outfp = fopen("test.txt","w");//打開編碼后保存的文件
	if(outfp == NULL)
	{
		printf("Open File \"test.txt\" For Write Err.\n");
		return;
	}
	EVP_EncodeInit(ctx);//Base64編碼初始化
	printf("文件\"Test.dat\" Base64編碼后為:\n");
	//循環讀取原文,並調用EVP_EncodeUpdate計算Base64編碼
	while(1)
	{
		inl = fread(in,1,1024,infp);
		if(inl <= 0)
			break;
		EVP_EncodeUpdate(ctx,out,&outl,in,inl);//編碼
		fwrite(out,1,outl,outfp);//輸出編碼結果到文件
		printf("%s",out);
	} 
	EVP_EncodeFinal(ctx,out,&outl);//完成編碼,輸出最后的數據。
	fwrite(out,1,outl,outfp);
	printf("%s",out);
	fclose(infp);
	fclose(outfp);	
	printf("對文件\"Test.dat\" Base64編碼完成,保存到\"test.txt\"文件.\n\n\n");
}

//Base64解碼
void tEVP_Decode()
{
	EVP_ENCODE_CTX *ctx;
        ctx = EVP_ENCODE_CTX_new();			//EVP編碼結構體
	char in[1024];					//輸入數據緩沖區
	int inl;						//輸入數據長度
	unsigned char out[1024];		//輸出數據緩沖區
	int outl;						//輸出數據長度
	FILE *infp;						//輸入文件句柄
	FILE *outfp;					//輸出文件句柄
	
	infp = fopen("test.txt","r");//打開待解碼的文件
	if(infp == NULL)
	{
		printf("Open File \"Test.txt\"  for Read Err.\n");
		return;
	}
	outfp = fopen("test-1.dat","wb");//打開解碼后保存的文件
	if(outfp == NULL)
	{
		printf("Open File \"test-1.txt\" For Write Err.\n");
		return;
	}
	EVP_DecodeInit(ctx);//Base64解碼初始化
	printf("開始對文件\"Test.txt\" Base64解碼...\n\n");
	//循環讀取原文,並調用EVP_DecodeUpdate進行Base64解碼
	while(1)
	{
		inl = fread(in,1,1024,infp);
		if(inl <= 0)
			break;
		EVP_DecodeUpdate(ctx,out,&outl,in,inl);//Base64解碼
		fwrite(out,1,outl,outfp);//輸出到文件
	} 
	EVP_DecodeFinal(ctx,out,&outl);//完成解碼,輸出最后的數據。
	fwrite(out,1,outl,outfp);
	fclose(infp);
	fclose(outfp);	
	printf("對文件\"Test.txt\" Base64解碼完成,保存為\"test-1.dat\"\n\n\n");
	
}
 
int main()
{
 
	tEVP_Encode();
	tEVP_Decode();
	
	return 0;
}

代碼中有中文,編譯運行可能出現亂碼,使用gcc編譯時可以使用如下參數:

  • -finput-charset 指定源文件(保存文件時選擇)的編碼方式(若不指定,編譯器默認是UTF-8)
  • -fexec-charset 指定可執行程序中的字符以什么編碼方式來表示,默認是UTF-8

編譯代碼的命令是:

gcc -o testbase64 testbase64.c -I /root/rocopenssl/include -L /root/rocopenssl/lib -lcrypto -lpthread -finput-charset=GBK -fexec-charset=UTF-8

測試中的用到一個test.dat 是個二進制文件,可以用echo命令生成,或者用二進制編輯工具生成。

執行./testbase64,結果如下圖:

作業

  1. 兩人一組
  2. 基於Socket實現TCP通信,一人實現服務器,一人實現客戶端
  3. 研究OpenSSL算法,測試對稱算法中的SM4,非對稱算法中的SM2,Hash算法中的SM3
  4. 選用合適的算法,基於混合密碼系統實現對TCP通信進行機密性、完整性保護。
  5. 學有余力者,對系統進行安全性分析和改進。

參考資料


歡迎關注“rocedu”微信公眾號(手機上長按二維碼)

做中教,做中學,實踐中共同進步!

rocedu



如果你覺得本文對你有幫助,請點一下左下角的“好文要頂”和“收藏該文



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM