非對稱加密算法也稱公開密鑰算法,其解決了對稱加密算法密鑰分配的問題,非對稱加密算法基本特色以下:算法
一、加密密鑰和解密密鑰不一樣併發
二、密鑰對中的一個密鑰能夠公開dom
三、根據公開密鑰很難推算出私人密鑰編碼
根據非對稱加密算法的特色,可用戶數字簽名、密鑰交換、數據加密。可是因爲非對稱加密算法較對稱加密算法加密速度慢不少,故最經常使用的用途是數字簽名和密鑰交換。加密
目前經常使用的非對稱加密算法有RSA, DH和DSA三種,但並不是均可以用於密鑰交換和數字簽名。而是RSA可用於數字簽名和密鑰交換,DH算法可用於密鑰交換,而DSA算法專門用戶數字簽名。spa
openssl支持以上三種算法,併爲三種算法提供了豐富的指令集,本章主要介紹RSA算法及相關指令code
RSA雖然能夠數字簽名、密鑰交換和數據加密,可是RSA加密數據速度慢,一般不使用RSA加密數據。因此最經常使用的功能就是數字簽名和密鑰交換,拋開數字簽名和密鑰交換的概念,實質上就是使用公鑰加密仍是使用私鑰加密的區別。因此咱們只要記住一句話:「公鑰加密,私鑰簽名」。orm
公鑰加密:用途是密鑰交換,用戶A使用用戶B的公鑰將少許數據加密發送給B,B用本身的私鑰解密數據blog
私鑰簽名:用途是數字簽名,用戶A使用本身的私鑰將數據的摘要信息加密一併發送給B,B用A的公鑰解密摘要信息並驗證ssl
opessl中RSA算法指令主要有三個,其餘指令雖有涉及,但此處再也不詳述。
指令 | 功能 |
genrsa | 生成並輸入一個RSA私鑰 |
rsa | 處理RSA密鑰的格式轉換等問題 |
rsautl | 使用RSA密鑰進行加密、解密、簽名和驗證等運算 |
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:~$
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
上述兩個指令是密鑰的生成及管理做用,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相關內容的時候在進行補充。