openssl 摘要和簽名驗證指令dgst使用詳解


1、信息摘要和數字簽名概述

信息摘要:對數據進行處理,得到一段固定長度的結果,其特點輸入:

1、輸出長度固定。即輸出長度和輸入長度無關。

2、不可逆。即由輸出數據理論上不能推導出輸入數據

4、對輸入數據敏感。當輸入數據變化極小時,輸出數據也會發生明顯的變化

5、防碰撞。即不同的數據數據得到相同輸出數據的可能性極低。

由於信息摘要有上述特點,一般保證數據的完整性,對一個大文件進行摘要運算,得到其摘要值。通過網絡或者其他渠道傳輸后,通過驗證其摘要值,確定大文件本身有沒有發生變化。

數字簽名:數字簽名其實分成兩步,首先對原始文件進行摘要運算,得到摘要值,然后使用公開密鑰算法中的私鑰對摘要值進行加密。其簽名和驗證過程如下圖所示

1

有數字簽名的過程可以知道,對發送信息進行數字簽名,可以保證數字簽名的完整性、真實性、不可抵賴性。即接收者可以確認消息的來源、消息的真實,發送者不可以抵賴自己發送的消息,與現實生活中簽名的作用大致相同。

2、摘要算法和數字簽名相關指令及用法

目前openssl提供的摘要算法有md4、md5、ripemd160、sha、sha1、sha224、sha256、sha512、sha384、wirlpool。可以通過openssl dgst -命令查看。

上面我們已經提到了,數字簽名分為摘要和加密兩部分。在openssl提供的指令中,並沒有區分兩者。而是在摘要算法指令中包含了簽名和校驗參數。例如我們適用openssl md5 -命令可以看到它提供的選項有簽名和驗證等參數。

在openssl中單獨使用摘要算法指令完成摘要或者簽名操作,也可以通過dgst完成相同的操作。在簽名的時候多數使用RSA私鑰或者DSA私鑰,當使用RSA私鑰的時候,我們可以使用單獨的摘要算法指令指定摘要算法進行簽名,但當使用DSA使用簽名的時候,就必須使用dgst指令,因為使用DSA簽名的時候必須使用DSA自身的摘要算法,而openssl沒有為它提供相應的指令。

復制代碼
/*有明文文件file.txt和RSA密鑰RSA.pem*/
xlzh@cmos:~/test$ ls
file.txt  RSA.pem
/*使用md5指令指定sha1算法,對file.txt進行簽名,生成簽名文件sign1.txt*/
xlzh@cmos:~/test$ openssl md5 -sha1 -sign RSA.pem -out sign1.txt file.txt
/*使用md5指令指定sha1算法,對file.txt進行簽名,生成簽名文件sign1.txt*/
xlzh@cmos:~/test$ openssl dgst -sha1 -sign RSA.pem -out sign2.txt file.txt
/*兩個簽名文件一樣,說明兩個指令完成相同的功能*/
xlzh@cmos:~/test$ diff sign1.txt sign2.txt
復制代碼

可以看到md5和dgst完成相同的功能。不過讓人糾結的是使用md5進行簽名的時候可以指定其他摘要算法,筆者覺得太別扭了。所以建議做摘要和簽名驗證時使用dgst指令,忘記其他……

dgst指令用法介紹如下

復制代碼
xlzh@cmos:~/test$ openssl dgst -
unknown option '-'
options are
-c              to output the digest with separating colons        //輸出的摘要信息以分號隔離,和-hex同時使用
-r              to output the digest in coreutils format           //指定輸出的格式
-d              to output debug info                               //輸出BIO調試信息
-hex            output as hex dump                                 //以16進制打印輸出結果
-binary         output in binary form                              //輸出二進制結果
-hmac arg       set the HMAC key to arg                            //指定hmac的key
-non-fips-allow allow use of non FIPS digest                       //允許使用不符合fips標准的摘要算法
-sign   file    sign digest using private key in file              //執行簽名操作,后面指定私鑰文件
-verify file    verify a signature using public key in file        //執行驗證操作,后面指定公鑰文件,與prverfify不能同時使用
-prverify file  verify a signature using private key in file       //執行驗證操作,后面指定密鑰文件,與verfify不能同時使用
-keyform arg    key file format (PEM or ENGINE)                    //指定密鑰文件格式,pem或者engine
-out filename   output to filename rather than stdout              //指定輸出文件,默認標准輸出
-signature file signature to verify                                //指定簽名文件,在驗證簽名時使用
-sigopt nm:v    signature parameter                                //簽名參數
-hmac key       create hashed MAC with key                         //制作一個hmac 使用key
-mac algorithm  create MAC (not neccessarily HMAC)                 //制作一個mac
-macopt nm:v    MAC algorithm parameters or key                    //mac算法參數或者key
-engine e       use engine e, possibly a hardware device.          //使用硬件或者三方加密庫
-md4            to use the md4 message digest algorithm            //摘要算法使用md4
-md5            to use the md5 message digest algorithm            //摘要算法使用md5
-ripemd160      to use the ripemd160 message digest algorithm      //摘要算法使用ripemd160
-sha            to use the sha message digest algorithm            //摘要算法使用sha
-sha1           to use the sha1 message digest algorithm           //摘要算法使用sha1
-sha224         to use the sha224 message digest algorithm         //摘要算法使用sha223
-sha256         to use the sha256 message digest algorithm         //摘要算法使用sha256
-sha384         to use the sha384 message digest algorithm         //摘要算法使用sha384
-sha512         to use the sha512 message digest algorithm         //摘要算法使用sha512
-whirlpool      to use the whirlpool message digest algorithm      //摘要算法使用whirlpool
復制代碼

3、dgst使用示例

1、僅做摘要運算而不做簽名操作

復制代碼
/*對file.txt文件使用sha1算法進行hash運算*/
xlzh@cmos:~/test$ openssl dgst -sha1 file.txt 
SHA1(file.txt)= c994aec2a9007221a9b9113b8ab60a60144740c9
/*指定–non-fips-allow參數,與fips標准有關,尚待研究*/
xlzh@cmos:~/test$ openssl dgst –sha1 –non-fips-allow file.txt 
SHA1(file.txt)= c994aec2a9007221a9b9113b8ab60a60144740c9 
/*指定-d參數,打印調試消息*/
xlzh@cmos:~/test$ openssl dgst -sha1 -d file.txt 
BIO[02469910]:ctrl(6) - FILE pointer
BIO[02469910]:ctrl return 0
BIO[02469910]:ctrl(108) - FILE pointer
BIO[02469910]:ctrl return 1
BIO[02469910]:read(0,8192) - FILE pointer
BIO[02469910]:read return 37
BIO[02469910]:read(0,8192) - FILE pointer
BIO[02469910]:read return 0
SHA1(file.txt)= c994aec2a9007221a9b9113b8ab60a60144740c9
BIO[02469910]:ctrl(1) - FILE pointer
BIO[02469910]:ctrl return 0
BIO[02469910]:Free - FILE pointer
/*指定-c -hex參數,以16進制打印結果*/
xlzh@cmos:~/test$ openssl dgst -sha1 -c -hex file.txt 
SHA1(file.txt)= c9:94:ae:c2:a9:00:72:21:a9:b9:11:3b:8a:b6:0a:60:14:47:40:c9
/*指定-r參數,輸出結果如下所示,然並卵……*/
xlzh@cmos:~/test$ openssl dgst -sha1 -r file.txt 
c994aec2a9007221a9b9113b8ab60a60144740c9 *file.txt
/*指定-binary參數,輸入結果為二進制*/
xlzh@cmos:~/test$ openssl dgst -sha1 -binary file.txt 
ɔ�©r!��;��
`G@xlzh@cmos:~/test$
復制代碼

2、使用RSA密鑰進行簽名驗證操作

復制代碼
/*摘要算法選取sha256,密鑰RSA密鑰,對file.txt進行簽名*/
xlzh@cmos:~/test$ openssl dgst -sign RSA.pem -sha256 -out sign.txt file.txt
/*使用RSA密鑰驗證簽名(prverify參數),驗證成功*/ 
xlzh@cmos:~/test$ openssl dgst -prverify RSA.pem -sha256 -signature sign.txt file.txt 
Verified OKt 
/*從密鑰中提取公鑰*/
xlzh@cmos:~/test$ openssl rsa -in RSA.pem -out pub.pem -pubout
writing RSA key
/*使用RSA公鑰驗證簽名(verify參數),驗證成功*/
xlzh@cmos:~/test$ openssl dgst -verify pub.pem -sha256 -signature sign.txt file.txt 
Verified OK
復制代碼

3、使用DSA密鑰進行簽名驗證操作

復制代碼
/*使用DSA算法,摘要算法sha256,對file.txt進行簽名*/
xlzh@cmos:~/test$ openssl dgst -sign DSA.pem -sha256 -out sign.txt file.txt 
/*使用DSA密鑰驗證簽名*/
xlzh@cmos:~/test$ openssl dgst -prverify DSA.pem -sha256 -signature sign.txt file.txt
Verified OK
/*使用DSA算法,摘要算法dss1,對file.txt進行簽名*/
xlzh@cmos:~/test$ openssl dgst -sign DSA.pem -dss1 -out sign1.txt file.txt 
/*使用DSA密鑰驗證簽名*/
xlzh@cmos:~/test$ openssl dgst -prverify DSA.pem -dss1 -signature sign1.txt file.txt
Verified OK
/*提取公鑰*/
xlzh@cmos:~/test$ openssl dsa -in DSA.pem -out pub.pem -pubout
read DSA key
writing DSA key
/*使用DSA公鑰驗證簽名*/
xlzh@cmos:~/test$ openssl dgst -verify pub.pem -dss1 -signature sign1.txt file.txt 
Verified OK
/*使用DSA公鑰驗證簽名*/
xlzh@cmos:~/test$ openssl dgst -verify pub.pem -sha256 -signature sign.txt file.txt 
Verified OK
xlzh@cmos:~/test$
復制代碼

根據dgst man手冊的定義,如果使用DSA算法進行簽名驗證,必須使用dss1摘要算法,但是本實驗證明使用其他摘要算法也可以簽名驗證。此處不明白,希望大牛指點……

4、HMAC的使用

MAC 消息認證碼,構造方法可以基於hash,也可以基於對稱加密算法,HMAC是基於hash的消息認證碼。數據和密鑰作為輸入,摘要信息作為輸出,常用於認證。

xlzh@cmos:~/test$ openssl dgst  -sha256 -hmac 123456  file.txt 
HMAC-SHA256(file.txt)= b8e92990b9fc2ac9b58fde06f4738dceb4fb1fc47b4d2234a9c3f152907b333a

例如用戶登錄服務器

1、服務器給客戶端發送一個隨機數

2、客戶端使用隨機數作為密鑰和用戶密碼做HMAC,結果發送給服務器

3、服務器去除存儲的用戶密碼,也是用隨機數與用戶密碼做HMAC,根據HMAC結果是否一樣確認用戶身份。

4、遺留問題

dgst中sigopt、mac、macopt參數的含義即使用方法,因為doc都沒給出具體例子,待研究openssl源碼后進行補充

為什么使用DSA簽名的時候可以選擇其他hash算法(man 手冊說只能使用dss1)

還有dgst的hmac和hmac參數,沒錯,你沒看錯,它的確提供了兩個完全一樣的參數,給出的解釋還不一樣,還是研究源碼去吧.

可惡的openssl……

 

 

轉自:https://www.cnblogs.com/gordon0918/p/5382541.html


免責聲明!

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



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