热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

(9)opensslenc(对称加密)

对称加密工具。了解对称加密的原理后就很简单了,原理部分见下文。opensslenc-ciphername[-infilename][-outfilename][-passarg][

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

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后使用,这样不依赖于硬件

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

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

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

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

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

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

-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选项作用相同,但是打印时直接退出工具,不进行加密或解密操作

 

支持的单向加密算法有:

-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编码方式进行编码,但对应的在解密前就需要先解码,解码后才能解密

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

对称加密机制:

1、根据指定的单向加密算法,对输入的明文密码进行单向加密(默认是md5),得到固定长度的加密密钥,即对称密钥

2、再根据指定的对称加密算法,使用对称密钥加密文件

3、最后重新编码加密后的文件

      即单向加密明文密码结果作为对称密钥、使用对称密钥加密文件对文件重新编码

对称解密机制(加密的逆向操作):

1、先解码文件

2、然后根据单向加密算法对解密时输入的明文密码计算得到对称密钥

3、依此对称密钥对称解密解码后的文件

因此,解密过程中使用的解码方式、单向加密和对称加密算法都必须一致,且输入的密码必须是正确密码。

但需要注意的一点是,解密时可以不指定salt,因为加密时使用的salt会记录下来,解密时可以读取该salt

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

技术分享图片

根据指定的单向加密算法(-md -md5),对输入的明文密码(123456)进行单向加密得到固定长度的加密密钥,即对称密钥(f447b...15af),再根据指定的对称加密算法(-des3),使用对称密钥加密文件,最后重新编码(-a 即-abse64)加密后的文件

 

  技术分享图片

示例:

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

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


[root@docker121 ssl]# cat b.txt 
123456

[root@docker121 ssl]# openssl enc -a -in b.txt -out b_base64.txt

[root@docker121 ssl]# cat b_base64.txt
MTIzNDU2Cg==


再以base64格式进行解码。


[root@docker121 ssl]# openssl enc -a -d -in b_base64.txt
123456
[root@docker121 ssl]# openssl enc -a -d -in b_base64.txt -out bd_base64.txt
[root@docker121 ssl]# cat bd_base64.txt
123456


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

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


[root@docker121 ssl]# echo "to be or not to be" > test.txt

[root@docker121 ssl]# openssl enc -pass pass:123456 -md md5 -des3 -a -in test.txt -out e_test.txt


-pass  指定明文密码

-md    指定对明文密码单向加密的算法,得到对称密钥

-des3 使用对称密钥对称加密文件

-a       对加密后的文件进行base64编码

 

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


[root@docker121 ssl]# cat e_test.txt 
U2FsdGVkX19QKanxgeD1ug1bEax99vkTj2GeihsIHzsmMAE/rDgO8A==


解密文件


[root@docker121 ssl]# openssl enc -d -a -pass pass:123456 -md md5 -des3 -in e_test.txt -out de_test.txt
[root@docker121 ssl]# cat de_test.txt
to be or not to be


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


[root@docker121 ssl]# openssl enc -pass pass:123456 -md md5 -des3 -S ‘abcdef123‘ -a -in test.txt -out e2_test.txt
[root@docker121 ssl]# cat e2_test.txt
U2FsdGVkX1+rze8SMAAAAEmS219zSQxGpmEgf5ff2U1U4CELKCM2Ng==


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


[root@docker121 ssl]# openssl enc -d -pass pass:123456 -md md5 -des3 -a -in e2_test.txt -out de2_test.txt 
[root@docker121 ssl]# cat de2_test.txt 
to be or not to be




[root@docker121 ssl]# openssl enc -d -pass pass:123456 -md md5 -des3 -S ‘abcdef123‘ -a -in e2_test.txt -out sde2_test.txt
[root@docker121 ssl]# cat sde2_test.txt
to be or not to be


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

加密时的情况。


[root@localhost 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@localhost 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@localhost tmp]# openssl enc -a -des3 -d -in test.1 -pass pass:123456 -md md5 -P
salt=FABC000000000000
key=885FC58E6C822AEFC8032B4B98FA0355F8482BD654739F3D
iv =5128FDED01EE1499




[root@localhost 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@localhost tmp]# openssl enc -a -desx -d -in test.1 -pass pass:123456 -md md5 -p
salt=FABC000000000000
key=885FC58E6C822AEFC8032B4B98FA0355F8482BD654739F3D
iv =5128FDED01EE1499


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

  


推荐阅读
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
author-avatar
两枚小瓶盖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有