OpenSSL之3DES用法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenSSL之3DES用法相关的知识,希望对你有一定的参考价值。

参考技术A 3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密文,这样:
3DES加密过程为:C=Ek3(Dk2(Ek1(P)))
3DES解密过程为:P=Dk1(EK2(Dk3(C)))

本文假设你已经安装好了OpenSSL,并且持有一份1.1.1的源码。
3DES相关的头文件在des.h中、源文件在crypto/des目录中。

# define DES_ENCRYPT 1
# define DES_DECRYPT 0
这里定义了加密和解密的类型。

typedef unsigned int DES_LONG;

这个结构定义了DES的密钥上下文。相关字段含义:
ks —— 16轮子密钥。

在1.1.1中,大多数的数据结构已经不再向使用者开放,从封装的角度来看,这是更合理的。如果你在头文件中找不到结构定义,不妨去源码中搜一搜。

void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
DES_key_schedule *ks1, DES_key_schedule *ks2,
DES_key_schedule *ks3, int enc);
使用电子密码本方式加解密一个分组。
ks1、ks2、ks3分别为传入的三个64位密钥。
其内部实现为:

可以看到内部使用了DES_encrypt3()这个内部分组加密函数,并且传入了3个密钥。

我们继续来看DES_encrypt3()是如何利用这3个密钥的。
void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
DES_key_schedule *ks2, DES_key_schedule *ks3)
其内部实现为:

可以看到内部又继续使用了DES_encrypt2()这个分组加密函数。没有必要再继续解开DES_encrypt2()了,因为它主要根据密钥做分组的加解密处理。

关于三个密钥的利用关系,在DES_encrypt3()中主要是做三次叠加运算:
使用第一个密钥做分组加密运算。
使用第二个密钥做分组解密运算。
使用第三个密钥做分组加密运算。

3DES的叠加运算,根据密钥的组合关系,经常又表现为以下模式:

void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
long length,
DES_key_schedule *ks1, DES_key_schedule *ks2,
DES_key_schedule *ks3, DES_cblock *ivec, int enc);
使用密文分组链加解密。
参数ivec为初使化向量,在本函数返回时会被更新,可用于下一次分组运算。
注:
从源码实现来看,虽然DES_ede3_cbc_encrypt()自身支持明文长度多于一个分组的计算,但是却没有处理填充,所以从统一封装来看,建议开发者在使用这个函数时,同DES_ecb_encrypt()的用法一样,传入单个分组。

下面这个例子演示了使用普通DES加密,3DES的DES的兼容模式解密(即3个密钥完全相同)。

输出:
f8a8707fea7d45cd
3132333435363738

openssl genrsa

genrsa用于生成RSA私钥,不会生成公钥,因为公钥提取自私钥,如果需要查看公钥或生成公钥,可以使用openssl rsa命令。

使用man genrsa查询其用法。

openssl genrsa [-out filename] [-passout arg] [-des] [-des3] [-idea] [numbits]

选项说明:

-out filename     :将生成的私钥保存至filename文件,若未指定输出文件,则为标准输出。

-numbits            :指定要生成的私钥的长度,默认为1024。该项必须为命令行的最后一项参数。

-des|-des3|-idea:指定加密私钥文件用的算法,这样每次使用私钥文件都将输入密码,太麻烦所以很少使用。

-passout args    :加密私钥文件时,传递密码的格式,如果要加密私钥文件时单未指定该项,则提示输入密码。传递密码的args的格式见openssl密码格式。

例如:

(1).生成512位的rsa私钥,输出到屏幕。

[root@docker-01 ~]# openssl genrsa 512
Generating RSA private key, 512 bit long modulus
...++++++++++++
.............++++++++++++
e is 65537 (0x10001)
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAK8qI3DboywLTrMqqcrEpNwU9TQM8INLIX2HSiqMmIWrX1xiTjB9
QmFodNn3Xi5hJiZnCN1nfNp4Hce38iF04DMCAwEAAQJAQ2NlwRxumRo8i8dFDUI7
3oOdlgnIWeqEluN+kAIJB5s0fNNFWjOxiYZBsDAxlsQgEUuSSIvSKcZENND3RcO5
2QIhAN0ksDPT5WuzJndcWReBxYUHXIgmNiah5yBW7rIdJIYHAiEAysYsBjj2y/TW
OAf9wwOquBq/8JiB/8ShIl40GCgvqXUCIEARgAcT7dS9C3jrRVh9HWeEEXfUcj3R
DDAfX3o03T8DAiB2RdTT5FH/cNWqZO7c2ryvGdsuqKXa24PpGe1k0bvLKQIhAMmT
uDm54o4dsMxUzANonxlZxAvabrL6a7oYaEZGtLwQ
-----END RSA PRIVATE KEY-----

(2).生成512位的rsa私钥,输出到指定的文件genrsa.txt。

[root@docker-01 ~]# openssl genrsa -out genrsa.txt 512
Generating RSA private key, 512 bit long modulus
.............................++++++++++++
..........++++++++++++
e is 65537 (0x10001)
[root@docker-01 ~]# cat genrsa.txt 
-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBAMU42HQTdJ3NIXbd7+4tTf0iXmu2ZZwESpBp6STtIObLfVPjGAnz
lhlbG3ji3ieqCWXcjRo+TAf+3ijvM+HTuuMCAwEAAQJBAKGiQAuJsmZtqsJvi+bo
rGUMWNPwLYBbJ/0JP/Fqgi+DH6La0gMPAf3I1yG08bFI5zyHLVTk+XV891OeLznm
RNECIQDrcyaVIWVXL2m+wuDUKwQGcWXJhQ/y3NwPEYls3eoMuwIhANZvimFuTR/P
bwn8P3DRUM/2qzGC265JZ4ZcRHZJ9vv5AiEAsEhq3sU+RuSs27K0+qWqQditSRBj
PIa4DGAo8GXGUvkCIGfqL6YdfLRwon+1RM0YMlBFWhqpLmocWlXLOsYT++OJAiBs
uLgQ08Jc932/HToE6OOakF8YAd/yzfLzf63lWUBMag==
-----END RSA PRIVATE KEY-----

(3).加密私钥文件,加密的密码为123456。

[root@docker-01 ~]# openssl genrsa -out genrsa.txt -des3 -passout pass:123456 512
Generating RSA private key, 512 bit long modulus
.......++++++++++++
.....++++++++++++
e is 65537 (0x10001)
[root@docker-01 ~]# cat genrsa.txt 
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,1CB5A892A6896232

+VTzFTHkZPifuuJfKfJ9ThlQVSUtQhDlmYLLA2tEEO+tILqRJ2Si835DqYCW/Gma
rMHI51riZfilT3GNp9HRdwLoGGtGPgtYA03pQQNC+zqqmpoBaHurRiI/ufm6J6uk
Bm6Sagm970rvnT5KpRm9H8KDJDpx4XibUUHHvano0l15rr38Nk2dN3FPS8NBLw/V
xW6MqhtUhQGlf88enULTYCwU+Qcx1eiuuRDrbEr9z3LRVRGNDhE6/xQMKTRjc4Zj
vrbJpHHVPry5jXv0aeNAgxDYjlnVl7Y3xc43YGmR1W1SuLg9wkItLaeJxPig/bTZ
sEmsNWone1rS4On4hBlAwj/nMj4SFFdw1w5cfwfljJ7FG26rJEaiL8SAlAUURbXh
zIkfSJMtdqrOk+b0Ztu890j67NODwygzu7nD2EK6+6o=
-----END RSA PRIVATE KEY-----
[root@docker-01 ~]# 

其实一般情况下能用到的选项也就"-out"和"numbits"

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

以上是关于OpenSSL之3DES用法的主要内容,如果未能解决你的问题,请参考以下文章

OpenSSL之内存用法

PHP版DES算法加密数据(3DES)另附openssl_encrypt版本

PHP 将 mcrypt 转换为 openssl

OpenSSL之ASN1用法

OpenSSL之EVP用法

PHP 使用 openssl 解密数据(使用 mcrypt 加密)