openssl是實現Transport Layer Security (TLS)和Secure Sockets Layer (SSL) 協議的工具庫,同時也是提供了通用密碼算法,如對稱密碼,非對稱密碼,數字簽名,消息摘要等等的密碼庫。openssl可以直接以命令行的方式使用,或者作爲動態鏈接庫在其他程序中使用。這篇博客先介紹命令行的使用方式。
查看可用命令
openssl list <option>
option設置爲-help
可以查看所有合法的option
january@vostro3470:~$ openssl list -help
Usage: list [options]
Valid options are:
-help Display this summary
-1 List in one column
-commands List of standard commands
-digest-commands List of message digest commands
-digest-algorithms List of message digest algorithms
-cipher-commands List of cipher commands
-cipher-algorithms List of cipher algorithms
-public-key-algorithms List of public key algorithms
-public-key-methods List of public key methods
-disabled List of disabled features
-missing-help List missing detailed help strings
-options val List options for specified command
測試命令是否可用
openssl no-<command>
如果command存在,則返回1,並打印<command>
;如果command不存在則返回0,並打印no-<command>
january@vostro3470:~$ openssl no-list
list
# 使用$?讀取命令返回值
january@vostro3470:~$ echo $?
1
january@vostro3470:~$ openssl no-ffff
no-ffff
january@vostro3470:~$ echo $?
0
january@vostro3470:~$
口令生成祕鑰
口令生成祕鑰,或者是主密鑰生成子祕鑰要通過Key Derivation Function(KDF)來實現。KDF的主要實現算法分別是pbkdf2、bcrypt、scrypt,目前openssl推薦使用pbkdf2。因此在使用口令加密時,需要加上選項-pbkdf2
來使用pbkdf2算法生成祕鑰,另外還可以使用選項-iter <interation times>
指定迭代次數。祕鑰生成算法和迭代次數需要在解密的時候使用,否則無法正確解密。
短塊填充模式
對於分組加密算法,當需要加密的內容不足一個塊時,一種解決方案就是將其填充到一個塊大小,openssl採用pkcs7的填充方式。該方法流程如下:
- 計算短塊相比正常塊缺少字符,把該值記爲c
- 給短塊填充c個字節,每個字節的內容爲c的值
如果沒有短塊的話,就增加一整個塊,塊中每個字節的內容爲塊大小。該方法的支持不同長度的塊,最大爲255字節,即一個字節能表示的最大的數。
pkcs5的填充和pkcs7的填充唯一的區別是pkcs5固定了塊大小爲8字節,而pkcs7可以支持不同大小的塊
pkcs即Public Key Cryptography Standards,是一些密碼算法的標準文件,想了解的話參考維基百科PKCS
對稱加密
使用aes-128-cbc進行PBE(password-based encryption)模式的加密,其中的-pbkdf2
和-iter 100
就是指定口令生成祕鑰算法(key derivation)的。
january@vostro3470:~/Desktop/code_protection$ openssl aes-128-cbc -pbkdf2 -iter 100 -e -in key_file -out key_file.aes
enter aes-128-cbc encryption password:
Verifying - enter aes-128-cbc encryption password:
january@vostro3470:~/Desktop/code_protection$ echo `cat key_file`
lQodMJXiCRSJYS3S7P36kr1Mp8YfY58V9DoKxVfCUVM=
january@vostro3470:~/Desktop/code_protection$ echo `cat key_file.aes`
Salted__����کk����o�����iH����.P��� ���u���jl��q��!y��IL��
january@vostro3470:~/Desktop/code_protection$ openssl aes-128-cbc -pbkdf2 -iter 100 -d -in key_file.aes -out key_file.aes.decrypt
enter aes-128-cbc decryption password:
january@vostro3470:~/Desktop/code_protection$ cat key_file.aes.decrypt
lQodMJXiCRSJYS3S7P36kr1Mp8YfY58V9DoKxVfCUVM=
非對稱加密
RSA
祕鑰生成
生成私鑰
使用genrsa
命令來生成私鑰
openssl genrsa [options] <key length>
使用-out <key_file>
將生成的祕鑰保存到<key_file>文件
january@vostro3470:~/Desktop/code_protection$ openssl genrsa -out private.pem 1024
Generating RSA private key, 1024 bit long modulus (2 primes)
........................+++++
...............................+++++
e is 65537 (0x010001)
january@vostro3470:~/Desktop/code_protection$ cat private.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDY3Tcd96m79dJOkqdADPm88stNaBwYbS6DjvKneRIAsmoRYSVc
wXVkI7vPeyMysY5HPLxIuvUAAja4cptyGV2LPM2x34qIIihvGJS7DRChrst7g47K
PzOJIFByeuhP/9CJug5ZU25Te6mXGjvyHylpzns9af05iRBYRLFHGTUMVwIDAQAB
AoGABZopW1fThayDA06cjXYIWY44HEbNOwBPDEz8DcF96pCxVsOYsH2655xYtLJs
pVma4FI8VvCldZuZCEjFpTvsg6kejwtd6Rtpki26ssXxjtwvt+j4PNnfEu4Etixs
cx/JPJiFrWxpRop3ZVOpNpBUaZHERkL4QtT+nobWqeW3LFECQQD1H7+n6dB3lSVv
psNZYvoEzKrsMvSbj9ckptmMcKn2Rf6/XDhnY2bBQMcx3695JWjdk7OyHXkafawq
3gkLwiNPAkEA4nx5tqbYbiPBhlIk99MIoPyINVoMDwKvjLpaT0yfMnb6m/8aaBTC
uwYaS3kbjdNUOywu9G446Igo7ozRbQDkeQJADuW6ESttpwbiepGpB7KzPT1vGeHS
6e1pBuo5CIcEXVpNrDWfm/D3msEkGgzdLkCuyeCjKC0QYiLHJufNpvBKkwJBAK50
dQhlUhbcgefmBEXEj0P54S0/VESHrBM5Q/ELMyEbFoTspjl/rFOFKuHxwnCnVJ1T
tkNfV4R9xRGi9HoDEvkCQQDX7krJLyLWnTVkgyT/Nif4XhDovLHAO+ORdIGF8l0H
5esbi6DMv89iO8oqA6gQO2qxK5/yBw2ZCaEvquwjh5YH
-----END RSA PRIVATE KEY-----
生成公鑰
使用rsa
命令來生成公鑰
openssl rsa -in <key_file> -pubout -out <pub_key>
使用-in <file>
選項指定輸入文件,-pubout
表示輸出公鑰,-out <file>
指定輸出文件
january@vostro3470:~/Desktop/code_protection$ openssl rsa -in private.pem -pubout -out public.pem
writing RSA key
january@vostro3470:~/Desktop/code_protection$ cat public.pem
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY3Tcd96m79dJOkqdADPm88stN
aBwYbS6DjvKneRIAsmoRYSVcwXVkI7vPeyMysY5HPLxIuvUAAja4cptyGV2LPM2x
34qIIihvGJS7DRChrst7g47KPzOJIFByeuhP/9CJug5ZU25Te6mXGjvyHylpzns9
af05iRBYRLFHGTUMVwIDAQAB
-----END PUBLIC KEY-----
加密
使用rsautl
命令來加密
openssl rsautl -encrypt -pubin -in <file> -inkey <key_file> -out <file>
-encrypt
表示加密,-publin
表示輸入的祕鑰文件爲公鑰,-inkey <key_file>
指定用於加密的公鑰文件
-in <file>
和-out <file>
指定加密操作的輸入輸出文件
january@vostro3470:~/Desktop/code_protection$ openssl rsautl -encrypt -pubin -in key_file -inkey public.pem -out key_file.rsa
january@vostro3470:~/Desktop/code_protection$ xxd key_file
00000000: 6c51 6f64 4d4a 5869 4352 534a 5953 3353 lQodMJXiCRSJYS3S
00000010: 3750 3336 6b72 314d 7038 5966 5935 3856 7P36kr1Mp8YfY58V
00000020: 3944 6f4b 7856 6643 5556 4d3d 9DoKxVfCUVM=
january@vostro3470:~/Desktop/code_protection$ xxd key_file.rsa
00000000: 7639 01e3 3854 2b7d 6c43 c009 a75f 10c2 v9..8T+}lC..._..
00000010: a0c5 bb94 1828 1338 77a3 3e00 07a4 d429 .....(.8w.>....)
00000020: f46c 833d 8191 aaeb c974 e2e2 7214 887b .l.=.....t..r..{
00000030: aea9 cfc7 7002 4d12 5d1b 6e52 4bb7 df50 ....p.M.].nRK..P
00000040: f10e 57a5 2783 5afe 2fa0 90b7 af99 4db8 ..W.'.Z./.....M.
00000050: 729c 2a94 0098 9806 f975 0251 9626 abe7 r.*......u.Q.&..
00000060: 05d4 83f0 ce63 6f5a 36aa dce8 0dd0 1a93 .....coZ6.......
00000070: 4a0d 7144 5f2b 259f e9d7 106b e048 dde1 J.qD_+%....k.H..
解密
使用rsautl
命令解密
openssl rsautl -decrypt -in <file> -inkey <key_file> -out <file>
-decrypt
表示解密,-inkey <key_file>
指定用於解密的私鑰文件,其他和加密類似
january@vostro3470:~/Desktop/code_protection$ openssl rsautl -decrypt -inkey private.pem -in key_file.rsa -out key_file.rsa.decrypt
january@vostro3470:~/Desktop/code_protection$ xxd key_file.rsa.decrypt
00000000: 6c51 6f64 4d4a 5869 4352 534a 5953 3353 lQodMJXiCRSJYS3S
00000010: 3750 3336 6b72 314d 7038 5966 5935 3856 7P36kr1Mp8YfY58V
00000020: 3944 6f4b 7856 6643 5556 4d3d 9DoKxVfCUVM=