骏马金龙 (新博客:www.junmajinlong.com)

网名骏马金龙,钟情于IT世界里的各种原理和实现机制,强迫症重症患者。爱研究、爱翻译、爱分享。特借此一亩三分田记录自己成长点滴!!!

openssl enc(对称加密)

openssl系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html


对称加密工具。了解对称加密的原理后就很简单了,原理部分见下文。

openssl enc -ciphername [-in filename] [-out filename] [-pass arg] [-e] [-d] [-a/-base64] [-k password] [-S salt] [-salt] [-md] [-p/-P]

选项说明:

-ciphername:指定对称加密算法(如des3),可独立于enc直接使用,如openssl des3或openssl enc -des3。推荐在enc后使用,这样不依赖于硬件

-in filename :输入文件,不指定时默认是stdin

-out filename:输出文件,不指定时默认是stdout

-e:对输入文件加密操作,不指定时默认就是该选项

-d:对输入文件解密操作,只有显示指定该选项才是解密

-pass:传递加、解密时的明文密码。若验证签名时实用的公钥或私钥文件是被加密过的,则需要传递密码来解密。密码的格式见"openssl 密码格式"

-k     :已被"-pass"替代,现在还保留是为了兼容老版本的openssl

-base64:在加密后和解密前进行base64编码或解密,不指定时默认是二进制。注意,编码不是加解密的一部分,而是加解密前后对数据的格式"整理"

-a:等价于-base64

-salt:单向加密时使用salt复杂化单向加密的结果,此为默认选项,且使用随机salt值

-S salt:不使用随机salt值,而是自定义salt值,但只能是16进制范围内字符的组合,即"0-9a-fA-F"的任意一个或多个组合

-p:打印加解密时salt值、key值和IV初始化向量值(也是复杂化加密的一种方式),解密时还输出解密结果,见后文示例

-P:和-p选项作用相同,但是打印时直接退出工具,不进行加密或解密操作

-md:指定单向加密算法,默认md5。该算法是拿来加密key部分的,见后文分析。

支持的单向加密算法有:

-md4            to use the md4 message digest algorithm
-md5            to use the md5 message digest algorithm
-ripemd160      to use the ripemd160 message digest algorithm
-sha            to use the sha message digest algorithm
-sha1           to use the sha1 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
-whirlpool      to use the whirlpool message digest algorithm

支持的对称加密算法有:

-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             
-aes-128-xts               -aes-192-cbc               -aes-192-cfb             
-aes-192-cfb1              -aes-192-cfb8              -aes-192-ctr             
-aes-192-ecb               -aes-192-gcm               -aes-192-ofb             
-aes-256-cbc               -aes-256-cbc-hmac-sha1     -aes-256-cfb             
-aes-256-cfb1              -aes-256-cfb8              -aes-256-ctr             
-aes-256-ecb               -aes-256-gcm               -aes-256-ofb             
-aes-256-xts               -aes128                    -aes192                  
-aes256                    -bf                        -bf-cbc                  
-bf-cfb                    -bf-ecb                    -bf-ofb                  
-blowfish                  -camellia-128-cbc          -camellia-128-cfb        
-camellia-128-cfb1         -camellia-128-cfb8         -camellia-128-ecb        
-camellia-128-ofb          -camellia-192-cbc          -camellia-192-cfb        
-camellia-192-cfb1         -camellia-192-cfb8         -camellia-192-ecb        
-camellia-192-ofb          -camellia-256-cbc          -camellia-256-cfb        
-camellia-256-cfb1         -camellia-256-cfb8         -camellia-256-ecb        
-camellia-256-ofb          -camellia128               -camellia192             
-camellia256               -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                
-id-aes128-GCM             -id-aes128-wrap            -id-aes128-wrap-pad      
-id-aes192-GCM             -id-aes192-wrap            -id-aes192-wrap-pad      
-id-aes256-GCM             -id-aes256-wrap            -id-aes256-wrap-pad      
-id-smime-alg-CMS3DESwrap  -idea                      -idea-cbc                 
-idea-cfb                  -idea-ecb                  -idea-ofb                
-rc2                       -rc2-40-cbc                -rc2-64-cbc              
-rc2-cbc                   -rc2-cfb                   -rc2-ecb                 
-rc2-ofb                   -rc4                       -rc4-40                  
-rc4-hmac-md5              -seed                      -seed-cbc                
-seed-cfb                  -seed-ecb                  -seed-ofb

在给出openssl enc命令用法示例之前,先解释下对称加密和解密的原理和过程。

对称加解密时,它们使用的密码是完全相同的,例如"123456",但这是密码,且是明文密码,非常不安全,所以应该对此简单密码进行复杂化。最直接的方法是使用单向加密计算出明文密码的hash值,单向加密后新生成的密码已经比较安全(称之为密钥比较好),可以作为对称加密时的对称密钥。另外,由于同一单向加密算法对相同明文密码的计算结果是完全一致的,这样解密时使用相同的单向加密算法就能计算出完全相同的密钥,也就是解密时的对称密钥。如果想要更安全,还可以在对称加密后对加密文件进行重新编码,如使用"base64"、二进制或hex编码方式进行编码,但对应的在解密前就需要先解码,解码后才能解密。

所以,将对称加、解密的机制简单概括如下:

对称加密机制:根据指定的单向加密算法,对输入的明文密码进行单向加密(默认是md5),得到固定长度的加密密钥,即对称密钥,再根据指定的对称加密算法,使用对称密钥加密文件,最后重新编码加密后的文件。即单向加密明文密码结果作为对称密钥、使用对称密钥加密文件、对文件重新编码。

对称解密机制:先解码文件,再根据单向加密算法对解密时输入的明文密码计算得到对称密钥,依此对称密钥对称解密解码后的文件。

因此,解密过程中使用的解码方式、单向加密和对称加密算法都必须一致,且输入的密码必须是正确密码。但需要注意的一点是,解密时可以不指定salt,因为加密时使用的salt会记录下来,解密时可以读取该salt。

如下图所示,分别是加密和解密过程示意图。

示例:

以加密/etc/fstab的备份文件/tmp/test.txt为例。

(1).首先测试openssl enc的编码功能。由于未指定密码选项"-k"或"-pass",所以仅仅只进行编码而不进行加密,因此也不会提示输入密码。

[root@xuexi tmp]# openssl enc -a -in test.txt -out test_base64.txt

[root@xuexi tmp]# cat test_base64.txt
CiMKIyAvZXRjL2ZzdGFiCiMgQ3JlYXRlZCBieSBhbmFjb25kYSBvbiBUaHUgTWF5
IDExIDA0OjE3OjQ0IDIwMTcKIwojIEFjY2Vzc2libGUgZmlsZXN5c3RlbXMsIGJ5
IHJlZmVyZW5jZSwgYXJlIG1haW50YWluZWQgdW5kZXIgJy9kZXYvZGlzaycKIyBT
ZWUgbWFuIHBhZ2VzIGZzdGFiKDUpLCBmaW5kZnMoOCksIG1vdW50KDgpIGFuZC9v
ciBibGtpZCg4KSBmb3IgbW9yZSBpbmZvCiMKVVVJRD1iMmE3MGZhZi1hZWE0LTRk
OGUtOGJlOC1jNzEwOWFjOWM4YjggLyAgICAgICAgICAgICAgICAgICAgICAgeGZz
ICAgICBkZWZhdWx0cyAgICAgICAgMCAwClVVSUQ9MzY3ZDZhNzctMDMzYi00MDM3
LWJiY2ItNDE2NzA1ZWFkMDk1IC9ib290ICAgICAgICAgICAgICAgICAgIHhmcyAg
ICAgZGVmYXVsdHMgICAgICAgIDAgMApVVUlEPWQ1MDUxMTNjLWRhYTYtNGMxNy04
YjAzLWIzNTUxY2VkMjMwNSBzd2FwICAgICAgICAgICAgICAgICAgICBzd2FwICAg
IGRlZmF1bHRzICAgICAgICAwIDAK

再以base64格式进行解码。

[root@xuexi tmp]# openssl enc -a -d -in test_base64.txt              
 
#
# /etc/fstab
# Created by anaconda on Thu May 11 04:17:44 2017
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=b2a70faf-aea4-4d8e-8be8-c7109ac9c8b8 /                       xfs     defaults        0 0
UUID=367d6a77-033b-4037-bbcb-416705ead095 /boot                   xfs     defaults        0 0
UUID=d505113c-daa6-4c17-8b03-b3551ced2305 swap                    swap    defaults        0 0

实际上,上述编码和解码的过程严格地说也是对称加密和解密,因为openssl enc默认会带上加密选项"-e",只不过因为没有指定输入密码选项,使用的加密密码为空而已,且单向加密算法使用的也是默认值。解密时也一样。

(2).测试使用des3对称加密算法加密test.txt文件。

[root@xuexi tmp]# openssl enc -a -des3 -in test.txt -out test.1 -pass pass:123456 -md md5

加密后,查看加密后文件test.1的结果。

[root@xuexi tmp]# cat test.1
U2FsdGVkX1+c/d4NsXnY6Pd7rcZjGSsMRJWQOP0s5sxH6aLE5iCYjKEAbGac//iR
wkUUh6a57OpUA3+OOCKB4z+IxBcKo67BUDGR9vYeCfkobH9F+mSfVzZbXBrJmxwf
921tJ+8K+yKB6DjJfufpW+DWXmH8MFyvK60wnYHsfUQOp81EvaUtEfqEKIS8hgg7
4NTOyww+/VMDdc2wmkf08XNQUPlVtLaSx3vuBisxRdu8raiKWGGOB7qCwELCxDqu
NaRCIh0VjjffGohAOMMsAQ2kFCDUKx0Z4Df5fvifhPXoHfsj2lI216BPG5Cy88K2
KV78DoBm4pnMAymo/HRRF95LjvWYZIN88hIVN67u2j9zqSGeuyJakMyDVhYYmrHl
sMr2YTbTwus2DiO6qAzt/0a9nocTVKfGR81Xsh0a0ZudjtrMl5H36YJawpldvUCa
DzXPsbpQrp0VGi2HvJ4EVKKEx2uh8XYWmJ4ytj1s1wtCR6wQhmERtInGwULWTyI+
agXStSB5XzsvAJRJvexsaNycj5lAoQ8O6YXEj7B0inB7nBQTFbwkXyvJqXpr1179
i67leYc59OvlhRMA+GLW4g/Mg5dN5SBmgt1ChOJs4887zAUyLYrLvR4zDK6IQN/M
P6F15c9V+m9pw2t32sUQQmYrYqOV/AQf0t0EwvA0Myjmfqtvmp555Q==

解密文件test.1。

[root@xuexi tmp]# openssl enc -a -des3 -d -in test.1 -out test.2 -pass pass:123456 -md md5 

[root@xuexi tmp]# cat test.2
 
#
# /etc/fstab
# Created by anaconda on Thu May 11 04:17:44 2017
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=b2a70faf-aea4-4d8e-8be8-c7109ac9c8b8 /                       xfs     defaults        0 0
UUID=367d6a77-033b-4037-bbcb-416705ead095 /boot                   xfs     defaults        0 0
UUID=d505113c-daa6-4c17-8b03-b3551ced2305 swap                    swap    defaults        0 0

(3).加密时带上点盐salt。其实不写时默认就已经加入了,只不过是加入随机盐值。使用-S可以指定明确要使用的盐的值。但是盐的值只能是16进制范围内字符的组合,即"0-9a-fA-F"的任意一个或多个组合。

[root@xuexi tmp]# openssl enc -a -des3 -S 'Fabc' -in test.txt -out test.1 -pass pass:123456 -md md5    

解密。解密时不用指定salt值,即使指定了也不会影响解密结果。      

[root@xuexi tmp]# openssl enc -a -des3 -d -in test.1 -pass pass:123456 -md md5               
 
#
# /etc/fstab
# Created by anaconda on Thu May 11 04:17:44 2017
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=b2a70faf-aea4-4d8e-8be8-c7109ac9c8b8 /                       xfs     defaults        0 0
UUID=367d6a77-033b-4037-bbcb-416705ead095 /boot                   xfs     defaults        0 0
UUID=d505113c-daa6-4c17-8b03-b3551ced2305 swap                    swap    defaults        0 0
[root@xuexi tmp]# openssl enc -a -des3 -d -S 'Fabcxdasd' -in test.1 -pass pass:123456 -md md5
 
#
# /etc/fstab
# Created by anaconda on Thu May 11 04:17:44 2017
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=b2a70faf-aea4-4d8e-8be8-c7109ac9c8b8 /                       xfs     defaults        0 0
UUID=367d6a77-033b-4037-bbcb-416705ead095 /boot                   xfs     defaults        0 0
UUID=d505113c-daa6-4c17-8b03-b3551ced2305 swap                    swap    defaults        0 0

(4).在测试下"-p"和"-P"选项的输出功能。小写字母p不仅输出密钥算法结果,还输出加解密的内容,而大写字母P则只输出密钥算法结果。

加密时的情况。

[root@xuexi tmp]# openssl enc -a -des3 -S 'Fabc' -in test.txt -out test.1 -pass pass:123456 -md md5 -p
salt=FABC000000000000
key=885FC58E6C822AEFC8032B4B98FA0355F8482BD654739F3D
iv =5128FDED01EE1499

其中key就是单向加密明文密码后得到的对称密钥,iv是密码运算时使用的向量值。

再看解密时的情况,此处加上了salt。

[root@xuexi tmp]# openssl enc -a -des3 -d -S 'Fabc' -in test.1 -pass pass:123456 -md md5 -P
salt=FABC000000000000
key=885FC58E6C822AEFC8032B4B98FA0355F8482BD654739F3D
iv =5128FDED01EE1499

若解密时不指定salt,或者随意指定salt,结果如下。

[root@xuexi tmp]# openssl enc -a -des3 -d -in test.1 -pass pass:123456 -md md5 -P         
salt=FABC000000000000
key=885FC58E6C822AEFC8032B4B98FA0355F8482BD654739F3D
iv =5128FDED01EE1499
[root@xuexi tmp]# openssl enc -a -des3 -S 'FabM' -d -in test.1 -pass pass:123456 -md md5 -P
salt=FABC000000000000
key=885FC58E6C822AEFC8032B4B98FA0355F8482BD654739F3D
iv =5128FDED01EE1499

可见,解密时,只要指定和加密时相同编码格式和单向加密算法,密钥的结果就是一样的,且解密时明确指定salt是无意义的,因为它可以读取到加密时使用的salt。

甚至,解密时指定不同的对称加密算法,密钥结果也是一样的。

[root@xuexi tmp]# openssl enc -a -desx -d -in test.1 -pass pass:123456 -md md5 -p 
salt=FABC000000000000
key=885FC58E6C822AEFC8032B4B98FA0355F8482BD654739F3D
iv =5128FDED01EE1499

由此,能推理出对称加密时使用的对称密钥和对称算法是毫无关系的。

posted @ 2017-07-03 15:47  骏马金龙  阅读(5763)  评论(0编辑  收藏  举报