openssl 加解密简单探索

背景

在工作中用到了Java 的Blowfish加解密,后改为openssl命令实现,发现openssl有很多不熟悉的地方,进行了简单的探索,再此把这次探索的内容记录下来。主要是进行enc命令的探索。

命令说明

命令结构

openssl command [ command_opts ] [ command_args ]

enc 命令

openssl enc -ciphername [-in filename] [-out filename] [-pass arg] [-e] 
 
[-d] [-a/-base64] [-A] [-k password] [-kfile filename] [-K key] [-iv IV] [-S salt]
 
[-salt] [-nosalt] [-z] [-md] [-p] [-P] [-bufsize number] [-nopad] [-debug] [-none] 
 
[-engine id]

选项说明:

-ciphername:对称算法名称,此命令有两种使用方式:-ciphername方式或者省略enc直接使用ciphername。
 
-in filename:要加密/解密的输入文件,默认为标准输入。
 
-out filename:要加密/解密的输出文件,默认为标准输出。
 
-pass arg:输入文件如果有密码保护,指定密码来源。
 
-e:进行加密操作,默认操作。可以省略
 
-d:进行解密操作。
 
-a:使用base64编码对加密结果进行处理。加密后进行base64编码,解密前进行base64解密。
 
-base64:同-a选项。
 
-A:默认情况下,base64编码为一个多行的文件。使用此选项,可以让生成的结果为一行。解密时,必须使用同样的选项,否则读取数据时会出错。
 
-k:指定加密口令,不设置此项时,程序会提示用户输入口令。
 
-kfile:指定口令存放文件。可以从这个口令存放文件的第一行读取加密口令。
 
-K key:使用一个16进制的输入口令。如果仅指定-K key而没有指定-k password,必须用-iv选项指定IV。当-K key和-k password都指定时,用-K选项给定的key将会被使用,而使用password来产生初始化向量IV。不建议两者都指定。
 
-iv IV:手工指定初始化向量(IV)的值。IV值是16进制格式的。如果仅使用-K指定了key而没有使用-k指定password,那么就需要使用-iv手工指定IV值。如果使用-k指定了password,那么IV值会由这个password的值来产生。
 
-salt:产生一个随机数,并与-k指定的password串联,然后计算其Hash值来防御字典攻击和rainbow table攻击。
-S salt:使用16进制的salt。
 
-nosalt:表示不使用salt。
 
-z:压缩数据(前提是OpenSSL编译时加入了zip库)。
 
-md:指定摘要算法。如:MD5  SHA1  SHA256等。
 
-p:打印出使用的salt、口令以及初始化向量IV。
 
-P:打印出使用的salt、口令以及IV,不做加密和解密操作,直接退出。
 
-bufsize number:设置I/O操作的缓冲区大小。因为一个加密的文件可能会很大,每次能够处理的数据是有限的。
 
-nopad:没有数据填充(主要用于非对称加密操作)。
 
-debug:打印调试信息。
 
-none:不对数据进行加密操作。
 
-engine:指定硬件引擎。

salt(盐)、-k(密码)、key (-K)、iv之间的关系探索

加解密的时候我们真正使用的-K iv来进行字符的加解密,但是我们有时并不输入长长的key和iv,而是使用密码(-k),为了是防止字典攻击,彩虹表攻击我们使用salt。使用salt的时候默认都是随机生成的(-p可以打印出来),每次的key和iv都不一样,但是解密的时候却只需要知道密码就可以这是为什么?

不加salt情况

root@ucss2:~# echo -n "asd" | openssl enc -k "passwd" -a -bf-cbc -p -nosalt
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
key=0D6BE69B264717F2DD33652E212B1731
iv =04B4A647B7C11AE7
Nmd5naBmros= 
root@ucss2:~# echo -n "asd" | openssl enc -k "passwd" -a -bf-cbc -p -nosalt
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
key=0D6BE69B264717F2DD33652E212B1731
iv =04B4A647B7C11AE7
Nmd5naBmros=
#解密
root@ucss2:~# echo "Nmd5naBmros=" | openssl enc -k "passwd" -a -bf-cbc -p -nosalt -d 
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
key=0D6BE69B264717F2DD33652E212B1731
iv =04B4A647B7C11AE7
asd

每次的key和iv 都一样,所以生成base64密文都一样

加salt情况

root@ucss2:~# echo -n "asd" | openssl enc -k "passwd" -a -bf-cbc -p
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
salt=7E30AD9247349924
key=E911329C8723C900503D78FEA94B9AC3
iv =DB89BEB4988CB164
U2FsdGVkX19+MK2SRzSZJKZFQRxafkGT
root@ucss2:~# echo -n "asd" | openssl enc -k "passwd" -a -bf-cbc -p
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
salt=A568CC47507BFB58
key=14271A17828F2C5C4B542AF96DF80FBC
iv =4DB21FE1637E26E0
U2FsdGVkX1+laMxHUHv7WE7VSKbyzIVD
root@ucss2:~# echo "U2FsdGVkX1+laMxHUHv7WE7VSKbyzIVD" | openssl enc -k "passwd" -a -bf-cbc -p -d 
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
salt=A568CC47507BFB58
key=14271A17828F2C5C4B542AF96DF80FBC
iv =4DB21FE1637E26E0
asdroot@ucss2:~#  
root@ucss2:~# echo "U2FsdGVkX19+MK2SRzSZJKZFQRxafkGT" | openssl enc -k "passwd" -a -bf-cbc -p -d 
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
salt=7E30AD9247349924
key=E911329C8723C900503D78FEA94B9AC3
iv =DB89BEB4988CB164
asdroot@ucss2:~# 

因为salt是随机的,每次的key和iv都不一样,导致生成的密文每次都不相同,这个时候就有疑问了,生成密文的时候是通过pass和salt,为什么解密的时候确不用???(怀疑密文中有salt)

加密:passwd+salt(通过某些算法生成)>key iv
解密:同样需要key iv ,但是我们在解密的时候却只知道 passwd,要知道我们是对称加密,所以还需要找到和加密相同的key iv

通过二进制查看对比加salt和不加salt密文

root@ucss2:~# echo -n "asd" | openssl enc -k "passwd"  -bf-cbc -p -out salt.bin
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
salt=965804FC4937FE54
key=559DA0581998B7E17AE08F3BBE296528
iv =E0037425FB5962EA 
root@ucss2:~# xxd salt.bin 
00000000: 5361 6c74 6564 5f5f 9658 04fc 4937 fe54  Salted__.X..I7.T
00000010: f55d bd06 2720 3eb8                      .]..' >.

root@ucss2:~# echo -n "asd" | openssl enc -k "passwd"  -bf-cbc -p -nosalt -out nosalt.bin
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
key=0D6BE69B264717F2DD33652E212B1731
iv =04B4A647B7C11AE7
root@ucss2:~# xxd nosalt.bin 
00000000: 3667 799d a066 ae8b                      6gy..f..

在这里插入图片描述
看出加salt的二进制文件比不加盐的多一行,另外哪一样里面存的就是salt信息(965804FC4937FE54)
这样咱们就可以很清楚就是因为在密文的开头放了salt所以我们能够只用密码就能够解密。

解密时,也需要指定是否有salt,不能有salt使用nosalt,也不能nosalt使用salt

root@ucss2:~# openssl enc -k "passwd"  -bf-cbc -p -in salt.bin -d -nosalt
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
key=0D6BE69B264717F2DD33652E212B1731
iv =04B4A647B7C11AE7
bad decrypt
139660630045120:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:564:
ЗM
   ē Э`. 
root@ucss2:~# openssl enc -k "passwd"  -bf-cbc -p -in nosalt.bin -d 
error reading input file

问题验证

密文的解密,既可以通过passwd也可以通过key iv,去解密。
但是在实际解密的时候

root@ucss2:~# openssl enc  -bf-cbc -p -in nosalt.bin -d  -K 0D6BE69B264717F2DD33652E212B1731 -iv 04B4A647B7C11AE7
salt=C0E4E7ACFE7F0000
key=0D6BE69B264717F2DD33652E212B1731
iv =04B4A647B7C11AE7
asdroot@ucss2:~# 
root@ucss2:~# 
root@ucss2:~# 
root@ucss2:~# openssl enc  -bf-cbc -p -in salt.bin -d  -K 559DA0581998B7E17AE08F3BBE296528 -iv E0037425FB5962EA
salt=802A80CAFC7F0000
key=559DA0581998B7E17AE08F3BBE296528
iv =E0037425FB5962EA
bad decrypt
140338444927424:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:564:
ªZBDL89¤?IMroot@ucss2:~# 
root@ucss2:~# openssl enc  -bf-cbc -p -in salt.bin -d  -K 559DA0581998B7E17AE08F3BBE296528 -iv E0037425FB5962EA -nosalt 
key=559DA0581998B7E17AE08F3BBE296528
iv =E0037425FB5962EA
bad decrypt
140719439557056:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:564:
ªZBDL89¤?IMroot@ucss2:~# 

没有salt的可以通过key iv解密,但是有salt的却不能。

因为上面说过(passwd+salt(通过某些算法生成)>key iv) ,密文中带有salt。此时用key iv去解析完全不用salt 不用密码,只要把密文中的salt给删除就应该能用key iv解析。

进行salt.bin文件的改造

vim -b salt.bin

执行
:%!xxd
删除第一行,然后更改第二行的序号。
在这里插入图片描述
更改后
在这里插入图片描述
:%!xxd -r
wq
保存退出。

root@ucss2:~# openssl enc  -bf-cbc -p -in salt.bin -d  -K 559DA0581998B7E17AE08F3BBE296528 -iv E0037425FB5962EA 
salt=A02A1A12FC7F0000
key=559DA0581998B7E17AE08F3BBE296528
iv =E0037425FB5962EA
asdroot@ucss2:~# 

修改后加salt的密文也能够被解析出来。

结论

  1. 在我们使用的时候最好加salt,同样的内容生成的密文却不同,这样可以保证我们的密文的安全性。
  2. salt会在密文中保存,在解密的时候,通过密码和密文中的salt可以生成和加密时一样的key iv从而保证我们的密文能够正常的解密。
  3. 有salt的密文我们可以修改然后通过key iv 就能正常进行解析(key iv 和密码同样重要)。
  4. 知道 key iv 是否能反推密码,不能,因为生成key iv用到了md5(摘要算法)不能反推。
  5. 使用 key iv 的能否加salt,不能,因为salt是为了生成key iv,已经有个key iv 之后salt就是无效的

相关文献

OpenSSL AES 算法中 Key 和 IV 是如何生成的?
Linux VIM编辑二进制文件
加盐的目的

注意事项

在进行字符串加密时用-n,否则加密字符串加密后带换行
echo -n “asd” | openssl enc -K 38653466333761623535636533373933 -iv 6662636463663630 -a -bf-cbc

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值