OpenSSL加解密使用

本章講解下openssl相關概念和加解密算法的基本使用

這篇文章講述以下幾點

  • 什么是OpenSSL
  • 基本功能
  • 密鑰、證書的編碼格式和后綴名
  • 對稱加密的基本使用
  • 生成公私鑰對
  • 非對稱加密的基本使用

1. 什么是OpenSSL

OpenSSL 是一個安全套接字層密碼庫,囊括主要的密碼算法、常用的密鑰和證書封裝管理功能及SSL協議,并提供豐富的應用程序供測試或其它目的使用。

2. 基本功能

openssl是一個開源程序的套件、這個套件有三個部分組成:一是libcryto,這是一個具有通用功能的加密庫,里面實現了眾多的加密庫;二是libssl,這個是實現ssl機制的,它是用于實現TLS/SSL的功能;三是openssl,是個多功能命令行工具,它可以實現加密解密,甚至還可以當CA來用,可以讓你創建證書、吊銷證書。

為了做個更簡單的區分,我分成下面3種,可能你看著會親切一些

  • 加解密庫(本章只討論加解密)
  • SSL協議實現
  • 一些經過封裝,方便你使用加解密和SSL的工具

****密鑰、證書的編碼格式和后綴名

目前有以下兩種編碼格式.

  • PEM - Privacy Enhanced Mail
    打開看文本格式,以"-----BEGIN-----"開頭, "-----END-----"結尾,內容是Base64編碼,查看PEM格式的信息可以用命令
    openssl rsa -in my.pem -text -noout
    Unix服務器偏向于使用這種編碼格式.
  • DER - Distinguished Encoding Rules
    打開看是二進制格式,不可讀,查看DER格式的信息可以用命令
    openssl rsa -in my.der -inform der -text -noout
    Java和Windows服務器偏向于使用這種編碼格式.

我們平時見到的多種后綴名,都是語義化的后綴,在生成密鑰的時候,比如我們私鑰的后綴名可以寫.pem .key,都是可以的,以下幾種為常用后綴

  • CRT - CRT應該是certificate的三個字母,其實還是證書的意思,常見于Unix系統,有可能是PEM編碼,也有可能是DER編碼,大多數應該是PEM編碼,相信你已經知道怎么辨別.

  • CER - 還是certificate,還是證書,常見于Windows系統,同樣的,可能是PEM編碼,也可能是DER編碼,大多數應該是DER編碼.

  • KEY - 通常用來存放一個公鑰或者私鑰,并非X.509證書,編碼同樣的,可能是PEM,也可能是DER.
    查看KEY的辦法:
    openssl rsa -in mykey.key -text -noout
    如果是DER格式的話,同理應該這樣了:
    openssl rsa -in mykey.key -text -noout -inform der

  • CSR - Certificate Signing Request,即證書簽名請求,這個并不是證書,而是向權威證書頒發機構獲得簽名證書的申請,其核心內容是一個公鑰(當然還附帶了一些別的信息),在生成這個申請的時候,同時也會生成一個私鑰,私鑰要自己保管好,查看的辦法:
    openssl req -noout -text -in my.csr
    (如果是DER格式的話照舊加上-inform der,這里不寫了)

3. 常用加解密算法使用

我們重點討論如何使用

1.對稱加密

我們需要用到 openssl enc 命令,先看下幫助文檔

$ openssl enc -h 

:<<!
-in <file>     輸入文件
-out <file>    輸出文件
-pass <arg>    密碼
-S             鹽,用于加鹽加密,請避免人為輸入,下面討論
-e             encrypt 加密操作
-d             decrypt 解密操作
-a/-base64     base64 encode/decode, depending on encryption flag  是否將結果base64編碼
-k             已被-pass參數取代
-kfile         已被-pass參數取代
-md            指定密鑰生成的摘要算法 默認MD5
-K/-iv         加密所需的key和iv向量,由輸入的-pass生成
-[pP]          print the iv/key (then exit if -P)  是否需要在控制臺輸出生成的 key和iv向量
-bufsize <n>   讀寫文件的I/O緩存,一般不需要指定
-engine e      指定三方加密設備,沒有環境,暫不實驗

Cipher Types  以下是部分算法,我們可以選擇用哪種算法加密
-aes-128-cbc               -aes-128-cbc-hmac-sha1     -aes-128-cfb              
-aes-128-cfb1              -aes-128-cfb8              -aes-128-ctr              
-aes-128-ecb               -aes-128-gcm               -aes-128-ofb      
…………
!

使用,默認從控制臺輸入密碼,如果不指定加密算法,是不會進行加密的,也不會報錯,比如我們不指定算法,只指定base64格式輸出,就相當于只做了base64編碼而已

/*對文件進行base64編碼*/
openssl enc -base64 -in plain.txt -out base64.txt
/*對base64格式文件進行解密*/
openssl enc -base64 -d -in base64.txt -out plain2.txt
/*使用diff命令查看可知解碼前后明文一樣*/
diff plain.txt plain2.txt

不同輸入密碼的方式

/*命令行輸入,密碼123456*/
openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass pass:123456
/*文件輸入,密碼123456*/
echo 123456 > passwd.txt
openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass file:passwd.txt
/*環境變量輸入,密碼123456*/
passwd=123456
export passwd
openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass env:passwd
/*從文件描述輸入*/ 
openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass fd:1  
/*從標準輸入輸入*/ 
openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass stdin 
  • 對稱加密的使用中,雖然我們輸入了-pass,指定了密碼,但是本質是采用key和iv向量進行加密的,我們輸入的-pass,會轉換成key和iv
  • 為了增強安全性,在把用戶密碼轉換成 key / iv 的時候需要使用鹽值,默認鹽值隨機生成。使用-S參數,則鹽值由用戶指定。也可指用-nosalt指定不使用鹽值,但降低了安全性,不推薦使用。
  • 因為本質是采用 key / iv 加密,所以我們可以直接用 key / iv 解密或者加密

手動指定Key和IV值,指定key / iv 后,-pass參數不起作用

/*手動指定key和iv值*/
$ openssl enc -aes-128-cbc -in plain.txt -out encrypt.txt  -K 1223 -iv f123 -p
salt=0B00000000000000
key=12230000000000000000000000000000
iv =F1230000000000000000000000000000
/*指定pass密碼,不起作用,注意Key和IV值是16進制*/
$ openssl enc -aes-128-cbc -in plain.txt -out encrypt.txt  -K 1223 -iv f123 -p -pass pass:123456
salt=F502F4B8DE62E0E5
key=12230000000000000000000000000000
iv =F1230000000000000000000000000000

2.公私鑰對的生成(這里演示RSA算法相關)

首先我們需要用到 openssl genrsa 命令,先看下幫助文檔,這是一個簡易的命令,為了方便我們生成自己的私鑰

$ openssl genrsa -h       

/*
usage: genrsa [args] [numbits]

 -des           生成的私鑰采用DES算法加密
 -des3          生成的私鑰采用DES3算法加密 (168 bit key)
 -seed          encrypt PEM output with cbc seed
 -aes128, -aes192, -aes256
                
以上幾個都是對稱加密算法的指定,因為我們長期會把私鑰加密,避免明文存放

 -out file       私鑰輸出位置
 -passout arg    輸出文件的密碼,如果我們指定了對稱加密算法,也可以不帶此參數,會有命令行提示你輸入密碼
*/

我們生成一個私鑰

~ ? openssl genrsa -out my.key -des3             

/*                                                                   
Generating RSA private key, 512 bit long modulus
...++++++++++++
.++++++++++++
e is 65537 (0x10001)
# 因為指定了des3算法,并且沒指定密碼,所以會要求我輸入密碼
Enter pass phrase for my.key:   
Verifying - Enter pass phrase for my.key:
------------------------------------------------------------
*/

~ ? cat my.key          

/*                                                                        
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,21A9C0CD76DFBF27

i1h8ZmZxOZxDHigtXs0tAIWNs7THoN4t00F4xmYP7gDEU8vwWXltZisUqMJ2KHgZ
ME70Tm2XvhEAwu3OLhCaV6Url+DJ/G6sMFpnvkebrW51Ndph87ZCRdhaOrXN2WVg
+/KNRv2dMh4c98zgoJqYiN6qqdY9Sztj0DMtjn2f9k7mU8l2oN5bmlO6dy+mX2ZB
Qaupx9PV2DZH7Yd5tcKLudCa44lJ9cJscnvIyzLhDHcrGytCsTeHNeVMx9gefd0p
DzMBruiNhmXSe8a067OT5mWMi7++4WOYYWfIj2bat/pxsBNo0gOxqcuV0G1RFEDA
uX0vk1ma3+hB01p51bPCjc2HF/nvs2s/YeYgJR/E3zuxQGMvi6G0uxVY10i5xhtb
mIXi1J5RSoVcj2gMXD3GasGANNG3hdTWC+g6hfq+DczmGl8uR9lXwg==
-----END RSA PRIVATE KEY-----

*/

我們可以指定私鑰長度,命令最后就是指定私鑰長度,默認512bit

openssl genrsa -out my.key -des3 1024

另外我們需要用到 openssl rsa 命令,我們會用它生成公鑰,先看下幫助文檔

$ openssl rsa -h

/*
 -inform arg     輸入文件編碼格式,只有pem和der兩種
 -outform arg    輸出文件編碼格式,只有pem和der兩種
 -in arg         input file  輸入文件
 -sgckey         Use IIS SGC key format
 -passin arg     如果輸入文件被對稱加密過,需要指定輸入文件的密碼
 -out arg        輸出文件位置
 -passout arg    如果輸出文件也需要被對稱加密,需要指定輸出文件的密碼

 -des            對輸出結果采用對稱加密 des算法
 -des3           對輸出結果采用對稱加密 des3算法
 -seed           
 -aes128, -aes192, -aes256

 以上幾個都是對稱加密算法的指定,生成私鑰的時候一般會用到,我們不讓私鑰明文保存

 -text           以明文形式輸出各個參數值
 -noout          不輸出密鑰到任何文件
 -modulus        輸出模數值
 -check          檢查輸入密鑰的正確性和一致性
 -pubin          指定輸入文件是公鑰
 -pubout         指定輸出文件是公鑰
 -engine e       指定三方加密庫或者硬件
*/

我們利用剛才生成的私鑰my.key,以此生成一個公鑰

~ ? openssl rsa -in my.key -pubout -out my_pub.key     

/*                                                             
Enter pass phrase for my.key: # 因為私鑰有密碼,我們需要輸入
writing RSA key
------------------------------------------------------------
*/

~ ? cat my_pub.key                            

/*                                                                      
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAN4QWx/qPoOllcE8ZcR5zBzrSVFh7NXY
4SJHB8+IM3Wv2aYi7F3GlZjpt6EP3vdd4x4cJnuPFnZ5mZ5wFPQ8xD0CAwEAAQ==
-----END PUBLIC KEY-----
*/

openssl rsa 命令的功能還有很多

  1. rsa 添加 和 去除 密鑰的對稱加密
/*生成不加密的RSA密鑰*/
$ openssl genrsa -out RSA.pem

Generating RSA private key, 512 bit long modulus
..............++++++++++++
.....++++++++++++
e is 65537 (0x10001)

/*為RSA密鑰增加口令保護*/
$ openssl rsa -in RSA.pem -des3 -passout pass:123456 -out E_RSA.pem

/*為RSA密鑰去除口令保護*/
$ openssl rsa -in E_RSA.pem -passin pass:123456 -out P_RSA.pem

/*比較原始后的RSA密鑰和去除口令后的RSA密鑰,是一樣*/
$ diff RSA.pem P_RSA.pem

2、修改密鑰的保護口令和算法

/*生成RSA密鑰*/
$ openssl genrsa -des3 -passout pass:123456 -out RSA.pem

Generating RSA private key, 512 bit long modulus
..................++++++++++++
......................++++++++++++
e is 65537 (0x10001)

/*修改加密算法為aes128,口令是123456*/

$ openssl rsa -in RSA.pem -passin pass:123456 -aes128 -passout pass:123456 -out E_RSA.pem

3、查看密鑰對中的各個參數

$ openssl rsa -in RSA.pem -des -passin pass:123456 -text -noout

4、提取密鑰中的公鑰并打印模數值

/*提取公鑰,用pubout參數指定輸出為公鑰*/
$ openssl rsa -in RSA.pem -passin pass:123456 -pubout -out pub.pem

/*打印公鑰中模數值*/
$ openssl rsa -in pub.pem -pubin -modulus -noout

Modulus=C35E0B54041D78466EAE7DE67C1DA4D26575BC1608CE6A199012E11D10ED36E2F7C651D4D8B40D93691D901E2CF4E21687E912B77DCCE069373A7F6585E946EF

5、轉換密鑰的格式

/*把pem格式轉化成der格式,使用outform指定der格式*/
$ openssl rsa -in RSA.pem -passin pass:123456 -des -passout pass:123456 -outform der -out rsa.der

/*把der格式轉化成pem格式,使用inform指定der格式*/
$ openssl rsa -in rsa.der -inform der -passin pass:123456 -out rsa.pem

3.利用已有的公私鑰對 ,進行非對稱加解密

我們這里需要用到 openssl rsautl 命令

注意:無論是使用公鑰加密還是私鑰加密,RSA每次能夠加密的數據長度不能超過RSA密鑰長度,并且根據具體的補齊方式不同輸入的加密數據最大長度也不一樣,而輸出長度則總是跟RSA密鑰長度相等。RSA不同的補齊方法對應的輸入輸入長度如下表

數據補齊方式 輸入數據長度 輸出數據長度 參數字符串
PKCS#1 v1.5 少于(密鑰長度-11)字節 同密鑰長度 -pkcs
PKCS#1 OAEP 少于(密鑰長度-11)字節 同密鑰長度 -oaep
PKCS#1 for SSLv23 少于(密鑰長度-11)字節 同密鑰長度 -ssl
不使用補齊 同密鑰長度 同密鑰長度 -raw

使用rsautl進行加密和解密操作,我們還是先看一下幫助文檔

$ openssl rsautl -h
Usage: rsautl [options]                  
-in file        input file                                           //輸入文件
-out file       output file                                          //輸出文件
-inkey file     input key                                            //輸入的密鑰
-keyform arg    private key format - default PEM                     //指定密鑰格式
-pubin          input is an RSA public                               //指定輸入的是RSA公鑰
-certin         input is a certificate carrying an RSA public key    //指定輸入的是證書文件
-ssl            use SSL v2 padding                                   //使用SSLv23的填充方式
-raw            use no padding                                       //不進行填充
-pkcs           use PKCS#1 v1.5 padding (default)                    //使用V1.5的填充方式
-oaep           use PKCS#1 OAEP                                      //使用OAEP的填充方式
-sign           sign with private key                                //使用私鑰做簽名
-verify         verify with public key                               //使用公鑰認證簽名
-encrypt        encrypt with public key                              //使用公鑰加密
-decrypt        decrypt with private key                             //使用私鑰解密
-hexdump        hex dump output                                      //以16進制dump輸出
-engine e       use engine e, possibly a hardware device.            //指定三方庫或者硬件設備
-passin arg    pass phrase source                                    //指定輸入的密碼

openssl rsautl 基本的加解密使用

/*生成RSA密鑰*/
$ openssl genrsa -des3 -passout pass:123456 -out RSA.pem 

Generating RSA private key, 512 bit long modulus
............++++++++++++
...++++++++++++
e is 65537 (0x10001)

/*提取公鑰*/
$ openssl rsa -in RSA.pem -passin pass:123456 -pubout -out pub.pem 

/*使用RSA作為密鑰進行加密,實際上使用其中的公鑰進行加密*/
$ openssl rsautl -encrypt -in plain.txt -inkey RSA.pem -passin pass:123456 -out enc.txt

/*使用RSA作為密鑰進行解密,實際上使用其中的私鑰進行解密*/
$ openssl rsautl -decrypt -in enc.txt -inkey RSA.pem -passin pass:123456 -out replain.txt

/*比較原始文件和解密后文件*/
$ diff plain.txt replain.txt 

/*使用公鑰進行加密*/
$ openssl rsautl -encrypt -in plain.txt -inkey pub.pem -pubin -out enc1.txt

/*私鑰進行解密*/
$ openssl rsautl -decrypt -in enc1.txt -inkey RSA.pem -passin pass:123456 -out replain1.txt

/*比較原始文件和解密后文件*/
$ diff plain.txt replain1.txt

簽名與驗證操作

/*提取PCKS8格式的私鑰*/
$ openssl pkcs8 -topk8 -in RSA.pem -passin pass:123456 -out pri.pem -nocrypt

/*使用RSA密鑰進行簽名,實際上使用私鑰進行加密*/
$ openssl rsautl -sign -in plain.txt -inkey RSA.pem -passin pass:123456 -out sign.txt

/*使用RSA密鑰進行驗證,實際上使用公鑰進行解密*/
$ openssl rsautl -verify -in sign.txt -inkey RSA.pem -passin pass:123456 -out replain.txt

/*對比原始文件和簽名解密后的文件*/
$ diff plain.txt replain.txt 

/*使用私鑰進行簽名*/
$ openssl rsautl -sign -in plain.txt -inkey pri.pem  -out sign1.txt

/*使用公鑰進行驗證*/
$ openssl rsautl -verify -in sign1.txt -inkey pub.pem -pubin -out replain1.txt

/*對比原始文件和簽名解密后的文件*/
$ cat plain replain1.txt
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內容

  • 1 基礎 1.1 對稱算法 描述:對稱加密是指加密過程和解密過程使用相同的密碼。主要分:分組加密、序列加密。 原理...
    御淺永夜閱讀 2,454評論 1 4
  • HTTPS介紹 超文本傳輸安全協議(英語:Hypertext Transfer Protocol Secure,縮...
    齊滇大圣閱讀 8,965評論 8 96
  • 01 經常看到一些年過40,50的中年婦女聚在一起家長里短,抱怨,訴苦。好像她的生活就沒有一點讓人滿意的地方,還有...
    蕭小月閱讀 1,328評論 0 2
  • 2016-12-12 連續幾周,心情持續性低落,身心疲憊,想要自殺,回家休息了幾天。一周前媽媽帶我看了心理醫生,確...
    大門子閱讀 830評論 0 0