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

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

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

一、輸出長度固定。即輸出長度和輸入長度無關。服務器

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

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

五、防碰撞。即不一樣的數據數據獲得相同輸出數據的可能性極低。spa

因爲信息摘要有上述特色,通常保證數據的完整性,對一個大文件進行摘要運算,獲得其摘要值。經過網絡或者其餘渠道傳輸後,經過驗證其摘要值,肯定大文件自己有沒有發生變化。debug

數字簽名:數字簽名其實分紅兩步,首先對原始文件進行摘要運算,獲得摘要值,而後使用公開密鑰算法中的私鑰對摘要值進行加密。其簽名和驗證過程以下圖所示調試

1

有數字簽名的過程能夠知道,對發送信息進行數字簽名,能夠保證數字簽名的完整性、真實性、不可抵賴性。即接收者能夠確認消息的來源、消息的真實,發送者不能夠抵賴本身發送的消息,與現實生活中籤名的做用大體相同。code

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

目前openssl提供的摘要算法有md四、md五、ripemd160、sha、sha一、sha22四、sha25六、sha5十二、sha38四、wirlpool。能夠經過openssl dgst -命令查看。orm

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

在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

三、dgst使用示例

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

/*對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$

二、使用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

三、使用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摘要算法,可是本實驗證實使用其餘摘要算法也能夠簽名驗證。此處不明白,但願大牛指點……

四、HMAC的使用

MAC 消息認證碼,構造方法能夠基於hash,也能夠基於對稱加密算法,HMAC是基於hash的消息認證碼。數據和密鑰做爲輸入,摘要信息做爲輸出,經常使用於認證。

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

例如用戶登陸服務器

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

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

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

四、遺留問題

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

爲何使用DSA簽名的時候能夠選擇其餘hash算法(man 手冊說只能使用dss1)

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

可惡的openssl……

相關文章
相關標籤/搜索