openssl 非對稱加密算法RSA命令詳解

一、非對稱加密算法概述

非對稱加密算法也稱公開密鑰算法,其解決了對稱加密算法密鑰分配的問題,非對稱加密算法基本特色以下:算法

一、加密密鑰和解密密鑰不一樣併發

二、密鑰對中的一個密鑰能夠公開dom

三、根據公開密鑰很難推算出私人密鑰編碼

根據非對稱加密算法的特色,可用戶數字簽名、密鑰交換、數據加密。可是因爲非對稱加密算法較對稱加密算法加密速度慢不少,故最經常使用的用途是數字簽名和密鑰交換。加密

目前經常使用的非對稱加密算法有RSA, DH和DSA三種,但並不是均可以用於密鑰交換和數字簽名。而是RSA可用於數字簽名和密鑰交換,DH算法可用於密鑰交換,而DSA算法專門用戶數字簽名。spa

openssl支持以上三種算法,併爲三種算法提供了豐富的指令集,本章主要介紹RSA算法及相關指令code

二、RSA算法相關指令及用法

RSA雖然能夠數字簽名、密鑰交換和數據加密,可是RSA加密數據速度慢,一般不使用RSA加密數據。因此最經常使用的功能就是數字簽名和密鑰交換,拋開數字簽名和密鑰交換的概念,實質上就是使用公鑰加密仍是使用私鑰加密的區別。因此咱們只要記住一句話:「公鑰加密,私鑰簽名」。orm

公鑰加密:用途是密鑰交換,用戶A使用用戶B的公鑰將少許數據加密發送給B,B用本身的私鑰解密數據blog

私鑰簽名:用途是數字簽名,用戶A使用本身的私鑰將數據的摘要信息加密一併發送給B,B用A的公鑰解密摘要信息並驗證ssl

opessl中RSA算法指令主要有三個,其餘指令雖有涉及,但此處再也不詳述。

指令 功能
genrsa 生成並輸入一個RSA私鑰
rsa 處理RSA密鑰的格式轉換等問題
rsautl 使用RSA密鑰進行加密、解密、簽名和驗證等運算

2.1 genrsa指令說明

genrsa用於生成密鑰對,其用法以下

xlzh@cmos:~$ openssl genrsa -
usage: genrsa [args] [numbits]                                                     //密鑰位數,建議1024及以上
 -des            encrypt the generated key with DES in cbc mode                    //生成的密鑰使用des方式進行加密
 -des3           encrypt the generated key with DES in ede cbc mode (168 bit key)  //生成的密鑰使用des3方式進行加密
 -seed
                 encrypt PEM output with cbc seed                                  //生成的密鑰仍是要seed方式進行
 -aes128, -aes192, -aes256
                 encrypt PEM output with cbc aes                                   //生成的密鑰使用aes方式進行加密
 -camellia128, -camellia192, –camellia256 
                 encrypt PEM output with cbc camellia                              //生成的密鑰使用camellia方式進行加密
 -out file       output the key to 'file                                           //生成的密鑰文件,可從中提取公鑰
 -passout arg    output file pass phrase source                                    //指定密鑰文件的加密口令,可從文件、環境變量、終端等輸入
 -f4             use F4 (0x10001) for the E value                                  //選擇指數e的值,默認指定該項,e值爲65537 -3              use 3 for the E value                                             //選擇指數e的值,默認值爲65537,使用該選項則指數指定爲3
 -engine e       use engine e, possibly a hardware device.                         //指定三方加密庫或者硬件
 -rand file:file:...
                 load the file (or the files in the directory) into                //產生隨機數的種子文件
                 the random number generator

能夠看到genrsa指令使用較爲簡單,經常使用的也就有指定加密算法、輸出密鑰文件、加密口令。咱們僅舉一個例子來講明

/*
 * 指定密鑰文件rsa.pem
 * 指定加密算法aes128
 * 指定加密密鑰123456
 * 指定密鑰長度1024
 **/
xlzh@cmos:~$ openssl genrsa -out rsa.pem -aes128 -passout pass:123456 1024
Generating RSA private key, 1024 bit long modulus
...............................................................++++++
.................................++++++
e is 65537 (0x10001)  // 默認模式65537
/*加密後的密鑰文件有加密算法等信息*/
xlzh@cmos:~$ cat rsa.pem 
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,4C23682B0D34D339ED7E44819A70B4F9

c9uHqqWbkcw3hjdQ/6fGuJcOFchd4+KfVZoJnnISnJBAhv3CelFAksKb2RKa5GoC
4Eq6SykCCSH8OboPoPBjd1ZdAsDl1Pio0vIJfAoQ4NmaRJ61+6onJ/HAx2NFTDjN
yrmsGOWejB6A3MT4KiXrvICnkKMsUY1Qp6ln2qOeVynmxeWAWiVZnjfm0OkScL1K
RGSuL32vecN5b1S8fZTYJTS3PQxjmyaw65zLX+8mUObanL9WhSLTz2eo/6xTzRbD
iOGMolfP/3ObqIAS3007qV48CtwWrlAa+RpbMVIiESN7BforOaNbh0s5NVuUnXYs
hx90iZj2M1L4i5SP8jKBunXPK6CHQtUQXpMH06nhoMNyZPtRQegFgZlwVOpOfoS5
khGAjJPnEXI7ah8oCNYO21JV6SlMFxK1lUeS3xCvM8Cd/zVBSzD7jg+axBJr+LpO
rhpmEFkStXHtFo3OK3BoyQHIzYEYH4S59xWO+dfrb2zUvkKsQKkV+TFMSZpr7b7U
iegUcK3NrbcWDApfTYmf/edublJBv816to+hYQLhXKfuzP5iMJmjnubhrXrA6S47
7XN6nil9DGWzUEMPnH6Brc8mj7JwFtxdpWDN2pY+VcJ04O98fO08c+4eSS3u0Y9f
TyxYy1C9nIWxF+t2Dulq94N4AQ2uyTXoVNhrmDYrJ9BUCugg6zx6xtU24aSGFvtn
ikgAU8JCX0GkcwU60tTLSxPNAWhNxJSJ5n7BXaV6QQ1GOiiKQlJAcRv2PMxNqVgK
poVq742+awsichrwqE5VIFW9AdSMyIT7w06IogyUrS+0+FmFS6qPtT3ZbFZakzkd
-----END RSA PRIVATE KEY-----
xlzh@cmos:~$

2.2 rsa指令說明

rsa指令用戶管理生成的密鑰,其用法以下

xlzh@cmos:~$ openssl rsa -
unknown option -
rsa [options] <infile >outfile     
where options are
 -inform arg     input format - one of DER NET PEM                      //輸入文件格式,默認pem格式
 -outform arg    output format - one of DER NET PEM                     //輸入文件格式,默認pem格式
 -in arg         input file                                             //輸入文件
 -sgckey         Use IIS SGC key format                                 //指定SGC編碼格式,兼容老版本,不該再使用
 -passin arg     input file pass phrase source                          //指定輸入文件的加密口令,可來自文件、終端、環境變量等
 -out arg        output file                                            //輸出文件
 -passout arg    output file pass phrase source                         //指定輸出文件的加密口令,可來自文件、終端、環境變量等
 -des            encrypt PEM output with cbc des                        //使用des加密輸出的文件
 -des3           encrypt PEM output with ede cbc des using 168 bit key  //使用des3加密輸出的文件
 -seed           encrypt PEM output with cbc seed                       //使用seed加密輸出的文件
 -aes128, -aes192, -aes256
                 encrypt PEM output with cbc aes                        //使用aes加密輸出的文件
 -camellia128, -camellia192, -camellia256
                 encrypt PEM output with cbc camellia                   //使用camellia加密輸出的文件呢
 -text           print the key in text                                  //以明文形式輸出各個參數值
 -noout          don't print key out                                    //不輸出密鑰到任何文件
 -modulus        print the RSA key modulus                              //輸出模數指
 -check          verify key consistency                                 //檢查輸入密鑰的正確性和一致性
 -pubin          expect a public key in input file                      //指定輸入文件是公鑰
 -pubout         output a public key                                    //指定輸出文件是公鑰
 -engine e       use engine e, possibly a hardware device.              //指定三方加密庫或者硬件
xlzh@cmos:~$

rsa指令操做示例以下

一、rsa添加和去除密鑰的保護口令

/*生成不加密的RSA密鑰*/
xlzh@cmos:~/test$ openssl genrsa -out RSA.pem
Generating RSA private key, 512 bit long modulus
..............++++++++++++
.....++++++++++++
e is 65537 (0x10001)
/*爲RSA密鑰增長口令保護*/
xlzh@cmos:~/test$ openssl rsa -in RSA.pem -des3 -passout pass:123456 -out E_RSA.pem
writing RSA key
/*爲RSA密鑰去除口令保護*/
xlzh@cmos:~/test$ openssl rsa -in E_RSA.pem -passin pass:123456 -out P_RSA.pem
writing RSA key
/*比較原始後的RSA密鑰和去除口令後的RSA密鑰,是同樣*/
xlzh@cmos:~/test$ diff RSA.pem P_RSA.pem

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

/*生成RSA密鑰*/
xlzh@cmos:~/test$ openssl genrsa -des3 -passout pass:123456 -out RSA.pem
Generating RSA private key, 512 bit long modulus
..................++++++++++++
......................++++++++++++
e is 65537 (0x10001)
/*修改加密算法爲aes128,口令是123456*/
xlzh@cmos:~/test$ openssl rsa -in RSA.pem -passin pass:123456 -aes128 -passout pass:123456 -out E_RSA.pem
writing RSA key

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

xlzh@cmos:~/test$ openssl rsa -in RSA.pem -des -passin pass:123456 -text -noout

四、提取密鑰中的公鑰並打印模數值

/*提取公鑰,用pubout參數指定輸出爲公鑰*/
xlzh@cmos:~/test$ openssl rsa -in RSA.pem -passin pass:123456 -pubout -out pub.pem
writing RSA key
/*打印公鑰中模數值*/
xlzh@cmos:~/test$ openssl rsa -in pub.pem -pubin -modulus -noout
Modulus=C35E0B54041D78466EAE7DE67C1DA4D26575BC1608CE6A199012E11D10ED36E2F7C651D4D8B40D93691D901E2CF4E21687E912B77DCCE069373A7F6585E946EF

五、轉換密鑰的格式

/*把pem格式轉化成der格式,使用outform指定der格式*/
xlzh@cmos:~/test$ openssl rsa -in RSA.pem -passin pass:123456 -des -passout pass:123456 -outform der -out rsa.der
writing RSA key
/*把der格式轉化成pem格式,使用inform指定der格式*/
xlzh@cmos:~/test$ openssl rsa -in rsa.der -inform der -passin pass:123456 -out rsa.pem

2.3 rsautl指令說明

上述兩個指令是密鑰的生成及管理做用,rsautl則是真正用於密鑰交換和數字簽名。實質上就是使用RSA公鑰或者私鑰加密。

而不管是使用公鑰加密仍是私鑰加密,RSA每次可以加密的數據長度不能超過RSA密鑰長度,而且根據具體的補齊方式不一樣輸入的加密數據最大長度也不同,而輸出長度則老是跟RSA密鑰長度相等。RSA不一樣的補齊方法對應的輸入輸入長度以下表

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

rsautl指令用法以下

xlzh@cmos:~$ openssl rsautl - 
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                                    //指定輸入的密碼

rsautl操做示例以下:

一、使用rsautl進行加密和解密操做

/*生成RSA密鑰*/
xlzh@cmos:~/test$ openssl genrsa -des3 -passout pass:123456 -out RSA.pem 
Generating RSA private key, 512 bit long modulus
............++++++++++++
...++++++++++++
e is 65537 (0x10001)
/*提取公鑰*/
xlzh@cmos:~/test$ openssl rsa -in RSA.pem -passin pass:123456 -pubout -out pub.pem 
writing RSA key
/*使用RSA做爲密鑰進行加密,實際上使用其中的公鑰進行加密*/
xlzh@cmos:~/test$ openssl rsautl -encrypt -in plain.txt -inkey RSA.pem -passin pass:123456 -out enc.txt
/*使用RSA做爲密鑰進行解密,實際上使用其中的私鑰進行解密*/
xlzh@cmos:~/test$ openssl rsautl -decrypt -in enc.txt -inkey RSA.pem -passin pass:123456 -out replain.txt
/*比較原始文件和解密後文件*/
xlzh@cmos:~/test$ diff plain.txt replain.txt 
/*使用公鑰進行加密*/
xlzh@cmos:~/test$ openssl rsautl -encrypt -in plain.txt -inkey pub.pem -pubin -out enc1.txt
/*使用RSA做爲密鑰進行解密,實際上使用其中的私鑰進行解密*/
xlzh@cmos:~/test$ openssl rsautl -decrypt -in enc1.txt -inkey RSA.pem -passin pass:123456 -out replain1.txt
/*比較原始文件和解密後文件*/
xlzh@cmos:~/test$ diff plain.txt replain1.txt

在進行這個實驗的時候有個疑惑,爲何相同的明文,使用密鑰加密和公鑰加密後的密文結果不同?在網上查詢了下,是由於rsa公鑰加密的時候根據填充模式填充隨機數,致使每次加密結果不一樣。

二、使用rsautl進行簽名和驗證操做

/*提取PCKS8格式的私鑰*/
xlzh@cmos:~/test$ openssl pkcs8 -topk8 -in RSA.pem -passin pass:123456 -out pri.pem -nocrypt
/*使用RSA密鑰進行簽名,實際上使用私鑰進行加密*/
xlzh@cmos:~/test$ openssl rsautl -sign -in plain.txt -inkey RSA.pem -passin pass:123456 -out sign.txt
/*使用RSA密鑰進行驗證,實際上使用公鑰進行解密*/
xlzh@cmos:~/test$ openssl rsautl -verify -in sign.txt -inkey RSA.pem -passin pass:123456 -out replain.txt
/*對比原始文件和簽名解密後的文件*/
xlzh@cmos:~/test$ diff plain.txt replain.txt 
/*使用私鑰進行簽名*/
xlzh@cmos:~/test$ openssl rsautl -sign -in plain.txt -inkey pri.pem  -out sign1.txt
/*使用公鑰進行驗證*/
xlzh@cmos:~/test$ openssl rsautl -verify -in sign1.txt -inkey pub.pem -pubin -out replain1.txt
/*對比原始文件和簽名解密後的文件*/
xlzh@cmos:~/test$ cat plain replain1.txt

要注意這裏的簽名和驗證過程其本質上是加解密操做,不是標準意義上的簽名和驗證。標準意義上簽名和驗證是須要增長摘要操做的,後續文章再詳細闡述。

三、小結

咱們能夠看到上述指令的參數中有涉及到證書相關的內容,等到後期咱們介紹CA相關內容的時候在進行補充。

相關文章
相關標籤/搜索