OpenSSL 提供了完整安全通信所需的編碼工具,諸如雜湊演算法(Hash algorithms)、加解密演算法(Encryption/Decryption algorithms) 及 SSL / TLS 協議的實現等。加上其開放源碼的特性,使得許多開源專案或商業套件都有其踪跡。OpenSSL 除了提供程式 API 擴充接口外,也有命令列模式的操作。本篇將著重於命令列模式下的操作。
請使用 "version" 為其參數:
$ openssl version
OpenSSL 0.9.8o 01 Jun 2010
若想要了解更詳細的資訊,還可加上 "-a" 的參數:
$ openssl version -a
OpenSSL 0.9.8o 01 Jun 2010
built on: Thu Feb 10 01:49:17 UTC 2011
platform: debian-i386
options: bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,1ong) blowfish(idx)
compiler: cc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -O3 -Wa,--noexecstack -g -Wall
OPENSSLDIR: "/usr/lib/ssl"
OpenSSL 沒有提供列出參數的功能,但當使用者使用任意非內建的參數時,OpenSSL 預設會列出支援的參數列表:
$ openssl -h
openssl:Error: '-h' is an invalid command.
Standard commands
asn1parse ca ciphers crl crl2pkcs7
dgst dh dhparam dsa dsaparam
ec ecparam enc engine errstr
gendh gendsa genrsa nseq ocsp
passwd pkcs12 pkcs7 pkcs8 prime
rand req rsa rsautl s_client
s_server s_time sess_id smime speed
spkac verify version x509
Message Digest commands (see the `dgst' command for more details)
md2 md4 md5 rmd160 sha
sha1
Cipher commands (see the `enc' command for more details)
aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb aes-256-cbc
aes-256-ecb base64 bf bf-cbc bf-cfb
bf-ecb bf-ofb cast cast-cbc cast5-cbc
cast5-cfb cast5-ecb cast5-ofb des des-cbc
des-cfb des-ecb des-ede des-ede-cbc des-ede-cfb
des-ede-ofb des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb
des-ofb des3 desx rc2 rc2-40-cbc
rc2-64-cbc rc2-cbc rc2-cfb rc2-ecb rc2-ofb
rc4 rc4-40
雖然上例使用 "-h" 為其參數,但是這個參數在 OpenSSL 是不支援的。使用其它非內建的參數,亦有相同的效果。
測試系統效能的方法有很多,其中一種是以運行一連串的演算法,並計算其運行時間。除了利用 OpenSSl 來協助我們了解系統的效能外,也可以進一步了解各種演算法在系統上運行的速度差異。
請使用 "speed" 為其參數:
$ openssl speed
Doing md2 for 3s on 16 size blocks: 216134 md2's in 2.98s
Doing md2 for 3s on 64 size blocks: 110034 md2's in 2.99s
Doing md2 for 3s on 256 size blocks: 37397 md2's in 2.99s
Doing md2 for 3s on 1024 size blocks: 10157 md2's in 3.00s
Doing md2 for 3s on 8192 size blocks: 1322 md2's in 3.00s
Doing md4 for 3s on 16 size blocks: 5080098 md4's in 2.96s
Doing md4 for 3s on 64 size blocks: 4274286 md4's in 3.00s
Doing md4 for 3s on 256 size blocks: 2889950 md4's in 2.94s
Doing md4 for 3s on 1024 size blocks: 1262368 md4's in 2.94s
Doing md4 for 3s on 8192 size blocks: 205260 md4's in 3.00s
Doing md5 for 3s on 16 size blocks: 4010019 md5's in 3.00s
Doing md5 for 3s on 64 size blocks: 3208521 md5's in 2.99s
Doing md5 for 3s on 256 size blocks: 1998828 md5's in 3.00s
Doing md5 for 3s on 1024 size blocks: 798719 md5's in 3.00s
Doing md5 for 3s on 8192 size blocks: 120678 md5's in 2.99s
Doing hmac(md5) for 3s on 16 size blocks: 3929559 hmac(md5)'s in 2.97s
Doing hmac(md5) for 3s on 64 size blocks: 3053322 hmac(md5)'s in 2.98s
Doing hmac(md5) for 3s on 256 size blocks: 1933109 hmac(md5)'s in 3.00s
Doing hmac(md5) for 3s on 1024 size blocks: 783766 hmac(md5)'s in 2.99s
Doing hmac(md5) for 3s on 8192 size blocks: 120355 hmac(md5)'s in 3.00s
Doing sha1 for 3s on 16 size blocks: 3374252 sha1's in 2.99s
Doing sha1 for 3s on 64 size blocks: 2356623 sha1's in 2.99s
Doing sha1 for 3s on 256 size blocks: 1211815 sha1's in 2.99s
Doing sha1 for 3s on 1024 size blocks: 415609 sha1's in 3.00s
Doing sha1 for 3s on 8192 size blocks: 58418 sha1's in 2.99s
...... (略)
此方式會進行幾個常見的演算法,包含雜湊演算法,對稱式加解密演算法及非對稱式加解密演算法。需要特別提醒使用者,因為此方式針對多款演算法進行測試,所以測試時間會非常久,但使用者可以使用鍵盤上的 "Ctrl" + "c" 的組合鍵終止測試。
請使用 "speed aes" 為其參數:
$ openssl speed aes
Doing aes-128 cbc for 3s on 16 size blocks: 9105763 aes-128 cbc's in 2.99s
Doing aes-128 cbc for 3s on 64 size blocks: 2389933 aes-128 cbc's in 2.99s
Doing aes-128 cbc for 3s on 256 size blocks: 610982 aes-128 cbc's in 3.00s
Doing aes-128 cbc for 3s on 1024 size blocks: 151887 aes-128 cbc's in 3.00s
Doing aes-128 cbc for 3s on 8192 size blocks: 19063 aes-128 cbc's in 3.00s
Doing aes-192 cbc for 3s on 16 size blocks: 7934694 aes-192 cbc's in 3.00s
Doing aes-192 cbc for 3s on 64 size blocks: 2051030 aes-192 cbc's in 2.99s
Doing aes-192 cbc for 3s on 256 size blocks: 508600 aes-192 cbc's in 2.95s
Doing aes-192 cbc for 3s on 1024 size blocks: 129624 aes-192 cbc's in 3.00s
Doing aes-192 cbc for 3s on 8192 size blocks: 16219 aes-192 cbc's in 3.00s
Doing aes-256 cbc for 3s on 16 size blocks: 6914734 aes-256 cbc's in 2.99s
Doing aes-256 cbc for 3s on 64 size blocks: 1779332 aes-256 cbc's in 3.00s
Doing aes-256 cbc for 3s on 256 size blocks: 448172 aes-256 cbc's in 2.99s
Doing aes-256 cbc for 3s on 1024 size blocks: 112342 aes-256 cbc's in 2.99s
Doing aes-256 cbc for 3s on 8192 size blocks: 13953 aes-256 cbc's in 2.99s
OpenSSL 0.9.8o 01 Jun 2010
built on: Thu Feb 10 01:49:17 UTC 2011
options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,1ong) aes(partial) blowfish(idx)
compiler: cc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -O3 -Wa,--noexecstack -g -Wall
available timing options: TIMES TIMEB HZ=100 [sysconf value]
timing function used: times
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-128 cbc 48726.49k 51155.76k 52137.13k 51844.10k 52054.70k
aes-192 cbc 42318.37k 43901.65k 44136.14k 44244.99k 44288.68k
aes-256 cbc 37001.92k 37959.08k 38371.92k 38474.32k 38228.42k
相對於前一指令,此方式僅測試 AES 對稱式加解密演算法,所以測試期間比較短。
請使用 "speed rsa" 為其參數:
$ openssh speed rsa
Doing 512 bit private rsa's for 10s: 8333 512 bit private RSA's in 9.99s
Doing 512 bit public rsa's for 10s: 95531 512 bit public RSA's in 9.97s
Doing 1024 bit private rsa's for 10s: 1367 1024 bit private RSA's in 9.98s
Doing 1024 bit public rsa's for 10s: 27114 1024 bit public RSA's in 9.98s
Doing 2048 bit private rsa's for 10s: 207 2048 bit private RSA's in 10.02s
Doing 2048 bit public rsa's for 10s: 7363 2048 bit public RSA's in 9.99s
Doing 4096 bit private rsa's for 10s: 30 4096 bit private RSA's in 10.14s
Doing 4096 bit public rsa's for 10s: 2007 4096 bit public RSA's in 9.97s
OpenSSL 0.9.8o 01 Jun 2010
built on: Thu Feb 10 01:49:17 UTC 2011
options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,1ong) aes(partial) blowfish(idx)
compiler: cc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -O3 -Wa,--noexecstack -g -Wall
available timing options: TIMES TIMEB HZ=100 [sysconf value]
timing function used: times
sign verify sign/s verify/s
rsa 512 bits 0.001199s 0.000104s 834.1 9581.8
rsa 1024 bits 0.007301s 0.000368s 137.0 2716.8
rsa 2048 bits 0.048406s 0.001357s 20.7 737.0
rsa 4096 bits 0.338000s 0.004968s 3.0 201.3
將前一指令的稍微替換後,也可以進行其它的演算法測試,如此方式將僅測試 RSA 非對稱式加解密演算法。
OpenSSL 支援常見的雜湊演算法(Hash algorithms),如 MD5, SHA1, SHA256 等。
請使用 "dgst -h" 為其參數:
$ openssl dgst -h
unknown option '-h'
options are
-c to output the digest with separating colons
-d to output debug info
-hex output as hex dump
-binary output in binary form
-sign file sign digest using private key in file
-verify file verify a signature using public key in file
-prverify file verify a signature using private key in file
-keyform arg key file format (PEM or ENGINE)
-signature file signature to verify
-binary output in binary form
-hmac key create hashed MAC with key
-engine e use engine e, possibly a hardware device.
-md5 to use the md5 message digest algorithm (default)
-md4 to use the md4 message digest algorithm
-md2 to use the md2 message digest algorithm
-sha1 to use the sha1 message digest algorithm
-sha to use the sha message digest algorithm
-sha224 to use the sha224 message digest algorithm
-sha256 to use the sha256 message digest algorithm
-sha384 to use the sha384 message digest algorithm
-sha512 to use the sha512 message digest algorithm
-mdc2 to use the mdc2 message digest algorithm
-ripemd160 to use the ripemd160 message digest algorithm
列表中可以發現,除了常見的 MD5, SHA1 及 SHA256 外,還有其它的雜湊演算法可供使用。
請使用 "dgst -md5" 為其參數,並以 "-c" 來指定目標檔案:
$ openssl dgst -md5 -c testfile
MD5(file)= f1:c9:64:5d:bc:14:ef:dd:c7:d8:a3:22:68:5f:26:eb
輸出結果顯示,testfile 這個檔案的 MD5 Hash 為 "f1:c9:64:5d:bc:14:ef:dd:c7:d8:a3:22:68:5f:26:eb"。
我們可以使用其它 MD5 演算法來驗證其正確性,例如 Debian/Ubuntu 的 coreutils 套件提供的 md5sum 指令。
$ md5sum testfile
f1c9645dbc14efddc7d8a322685f26eb file
輸出結果顯示,testfile 的 MD5 Hash 為 "f1c9645dbc14efddc7d8a322685f26eb"。這與 OpenSSL 的輸出結果吻合,只是在比較前,我們需要將 OpenSSL 輸出的結果刪去 ":" 冒號來進行比對。
請使用 "dgst -sha1" 為其參數,並以 "-c" 來指定目標檔案:
$ openssl dgst -sha1 -c testfile
SHA1(file)= 8c:20:6a:1a:87:59:9f:53:2c:e6:86:75:53:6f:0b:15:46:90:0d:7a
輸出結果顯示,testfile 這個檔案的 MD5 Hash 為 "8c:20:6a:1a:87:59:9f:53:2c:e6:86:75:53:6f:0b:15:46:90:0d:7a"。
我們可以使用其它 SHA1 演算法來驗證其正確性,例如 Debian/Ubuntu 的 coreutils 套件提供的 sha1sum 指令。
$ sha1sum testfile
8c206a1a87599f532ce68675536f0b1546900d7a file
輸出結果顯示,testfile 的 SHA1 Hash 為 "8c206a1a87599f532ce68675536f0b1546900d7a"。這與 OpenSSL 的輸出結果吻合,只是在比較前,我們需要將 OpenSSL 輸出的結果刪去 ":" 冒號來進行比對。
請使用 "enc -h" 為其參數:
$ openssl enc -h
unknown option '-h'
options are
-in input file
-out output file
-pass pass phrase source
-e encrypt
-d decrypt
-a/-base64 base64 encode/decode, depending on encryption flag
-k passphrase is the next argument
-kfile passphrase is the first line of the file argument
-md the next argument is the md to use to create a key
from a passphrase. One of md2, md5, sha or sha1
-K/-iv key/iv in hex is the next argument
-[pP] print the iv/key (then exit if -P)
-bufsize buffer size
-engine e use engine e, possibly a hardware device.
Cipher Types
-aes-128-cbc -aes-128-cfb -aes-128-cfb1
-aes-128-cfb8 -aes-128-ecb -aes-128-ofb
-aes-192-cbc -aes-192-cfb -aes-192-cfb1
-aes-192-cfb8 -aes-192-ecb -aes-192-ofb
-aes-256-cbc -aes-256-cfb -aes-256-cfb1
-aes-256-cfb8 -aes-256-ecb -aes-256-ofb
-aes128 -aes192 -aes256
-bf -bf-cbc -bf-cfb
-bf-ecb -bf-ofb -blowfish
-cast -cast-cbc -cast5-cbc
-cast5-cfb -cast5-ecb -cast5-ofb
-des -des-cbc -des-cfb
-des-cfb1 -des-cfb8 -des-ecb
-des-ede -des-ede-cbc -des-ede-cfb
-des-ede-ofb -des-ede3 -des-ede3-cbc
-des-ede3-cfb -des-ede3-cfb1 -des-ede3-cfb8
-des-ede3-ofb -des-ofb -des3
-desx -desx-cbc -rc2
-rc2-40-cbc -rc2-64-cbc -rc2-cbc
-rc2-cfb -rc2-ecb -rc2-ofb
-rc4 -rc4-40
從列表中得知,OpenSSL 支援 AES, DES, Blowfish(bf) 及 RC4 演算法等。
另外,雖然上例使用 "-h" 為其參數,但是這個參數在 OpenSSL 是不支援的。使用其它非內建的參數,亦有相同的效果。
請使用 "des" 為其參數,隨後附上 "-in" 參數指定欲加密的檔案,以及 "-out" 參數指定加密後的檔案名稱:
$ openssl des -in file -out file.des
執行後,OpenSSL 會提示使用者由鍵盤上輸入加密之密碼,如下:
enter des-cbc encryption password:
需要注意的是,為了安全性,此時不管鍵盤輸入什麼,畫面上都不會出現任何字元,否則若旁人經過時,可能會故意或不經意的記下你的密碼。直到輸入完成後,按下鍵盤上的 "Enter" 鍵即可。
OpenSSL 會再一次要求使用者輸入一次相同的密碼,如下:
Verifying - enter des-cbc encryption password:
此時使用者只需要輸入與先前一樣的密碼即可,在輸入過程中畫面上一樣都不會出現任何字元。最後加密的檔案將以 file.des 的名稱存在於磁碟中。
請使用 "des" 為其參數,因為 OpenSSL 指令預設為加密,所以若要切換成解密則需要再加上 "-d" (decrypt) 的參數,隨後附上 "-in" 參數指定欲加密的檔案,以及 "-out" 參數指定加密後的檔案名稱:
$ openssl des -d -in file.des -out file
執行後,OpenSSL 會提示使用者由鍵盤上輸入加密之密碼,如下:
enter des-cbc encryption password:
需要注意的是,為了安全性,此時不管鍵盤輸入什麼,畫面上都不會出現任何字元,否則若旁人經過時,可能會故意或不經意的記下你的密碼。直到輸入完成後,按下鍵盤上的 "Enter" 鍵即可。
此時若使用者輸入了正確的密碼,就會成功將 file.des 解密之檔案,以 file 的檔案名稱存在於磁碟上。
請使用 "des3" 為其參數,隨後附上 "-in" 參數指定欲加密的檔案,以及 "-out" 參數指定加密後的檔案名稱:
$ openssl des3 -in file -out file.des3
執行後,OpenSSL 會提示使用者由鍵盤上輸入加密之密碼,如下:
enter des-ede3-cbc encryption password:
需要注意的是,為了安全性,此時不管鍵盤輸入什麼,畫面上都不會出現任何字元,否則若旁人經過時,可能會故意或不經意的記下你的密碼。直到輸入完成後,按下鍵盤上的 "Enter" 鍵即可。
OpenSSL 會再一次要求使用者輸入一次相同的密碼,如下:
Verifying - enter des-ede3-cbc encryption password:
此時使用者只需要輸入與先前一樣的密碼即可,在輸入過程中畫面上一樣都不會出現任何字元。最後加密的檔案將以 file.des3 的名稱存在於磁碟中。
請使用 "des3" 為其參數,因為 OpenSSL 指令預設為加密,所以若要切換成解密則需要再加上 "-d" (decrypt) 的參數,隨後附上 "-in" 參數指定欲加密的檔案,以及 "-out" 參數指定加密後的檔案名稱:
$ openssl des3 -d -in file.des3 -out file
執行後,OpenSSL 會提示使用者由鍵盤上輸入加密之密碼,如下:
enter des-ede3-cbc encryption password:
需要注意的是,為了安全性,此時不管鍵盤輸入什麼,畫面上都不會出現任何字元,否則若旁人經過時,可能會故意或不經意的記下你的密碼。直到輸入完成後,按下鍵盤上的 "Enter" 鍵即可。
此時若使用者輸入了正確的密碼,就會成功將 file.des3 解密之檔案,以 file 的檔案名稱存在於磁碟上。
本範例將使用 AES-256-CBC 的模式進行操作。
請使用 "aes-256-cbc" 為其參數,隨後附上 "-in" 參數指定欲加密的檔案,以及 "-out" 參數指定加密後的檔案名稱:
$ openssl aes-256-cbc -in file -out file.aes
執行後,OpenSSL 會提示使用者由鍵盤上輸入加密之密碼,如下:
enter aes-256-cbc encryption password:
需要注意的是,為了安全性,此時不管鍵盤輸入什麼,畫面上都不會出現任何字元,否則若旁人經過時,可能會故意或不經意的記下你的密碼。直到輸入完成後,按下鍵盤上的 "Enter" 鍵即可。
OpenSSL 會再一次要求使用者輸入一次相同的密碼,如下:
Verifying - enter aes-256-cbc encryption password:
此時使用者只需要輸入與先前一樣的密碼即可,在輸入過程中畫面上一樣都不會出現任何字元。最後加密的檔案將以 file.aes 的名稱存在於磁碟中。
請使用 "aes-256-cbc" 為其參數,因為 OpenSSL 指令預設為加密,所以若要切換成解密則需要再加上 "-d" (decrypt) 的參數,隨後附上 "-in" 參數指定欲加密的檔案,以及 "-out" 參數指定加密後的檔案名稱:
$ openssl aes-256-cbc -d -in file.aes -out file
執行後,OpenSSL 會提示使用者由鍵盤上輸入加密之密碼,如下:
enter aes-256-cbc encryption password:
需要注意的是,為了安全性,此時不管鍵盤輸入什麼,畫面上都不會出現任何字元,否則若旁人經過時,可能會故意或不經意的記下你的密碼。直到輸入完成後,按下鍵盤上的 "Enter" 鍵即可。
此時若使用者輸入了正確的密碼,就會成功將 file.aes 解密之檔案,以 file 的檔案名稱存在於磁碟上。
$ openssl genrsa -out private.pem
Generating RSA private key, 512 bit long modulus
.++++++++++++
...++++++++++++
e is 65537 (0x10001)
執行後,OpenSSL 預設會產生長度為 512 bit 的私鑰。
我們可以使用額外指令參數來改成預設的私鑰長度。例如,產生 1024 bit 長度的私鑰,可以在上列指令的最後加上 "1024",如:
$ openssl genrsa -out private.pem 1024
Generating RSA private key, 1024 bit long modulus
.++++++
........................................................++++++
e is 65537 (0x10001)
以此類推,若是 "4096",則:
$ openssl genrsa -out private.pem 4096
Generating RSA private key, 4096 bit long modulus
......................................................................................++
..................++
e is 65537 (0x10001)
需要注意的是,愈長的私鑰被破解的機率愈低,但是相對地,我們在使用加密與解密的時間也會愈長。使用者可以自行評量。
請使用 "rsa" 為其參數,隨後附上 "-in" 參數指定私鑰檔案,"-out" 參數指定產生的公鑰檔案名稱,"-outform" 參數指定公鑰的輸出格式,以及 "-pubout" 參數結尾:
$ openssl rsa -in private.pem -out public.pem -outform PEM -pubout
writing RSA key
執行後,OpenSSL 會產生 public.pem 的檔案在磁碟中。
請使用 "rsautl" 為其參數,隨後附上 "-encrypt" 參數指定加密的運行,"-inkey" 參數指定密鑰檔案,"-pubin" 參數將公鑰產生於加密檔案中,"-in" 參數指定欲加密的檔案,以及 "-out" 參數指定加密後的檔案名稱:
$ openssl rsautl -encrypt -inkey public.pem -pubin -in file -out file.rsa
執行後,OpenSSL 會產生 file.rsa 的檔案在磁碟中。
注意,RSA 非對稱式加解密演算法因為先天的限制,無法加密過大的檔案,若遇到此問題時,OpenSSL 會輸出如下的錯誤訊息:
RSA operation error
13931:error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size:rsa_pk1.c:151:
若遇到此問題時,最簡單的方式就是使用對稱式的加解密演算法,而不是非對稱式的加解密演算法。
請使用 "rsautl" 為其參數,隨後附上 "-decrypt" 參數指定解密的運行,"-inkey" 參數指定密鑰檔案,"-in" 參數指定欲解密的檔案,以及 "-out" 參數指定解密後的檔案名稱:
$ openssl rsautl -decrypt -inkey private.pem -in file.rsa -out file
執行後,OpenSSL 會產生 file 的檔案在磁碟中。
本篇範例介紹了 RSA 非對稱式加解密檔案的操作。當然除了本系列文章的介紹外,OpenSSL 還提供許多好用的功能,就請使用者自行探索囉。