文档章节

openssl AES 加密/解密

qlee
 qlee
发布于 2017/11/01 22:19
字数 989
阅读 4457
收藏 1

AES算法

AES进行加/解密需要考虑下面三个设置。

密钥

使用的密钥长度为128/192/256位,这里以128位为例

初始向量

初始向量位128位

填充

AES以128位,即16字节为单位进行操作,如果明文长度不是16的整数倍就需要进行填充,openssl默认以PKCS#7方式进行填充。PKCS#7填充时将明文长度扩充为16的整数倍,每一个填充的字节值为填充的长度。

例如:

  • 如明文长度为8,填充8个字节,每个字节均为0x8。DD表示明文,08为填充。

| DD DD DD DD DD DD DD DD 08 08 08 08 08 08 08 08 |

  • 如明文长度为16,额外填充16个字节。DD表示明文,10为填充。

| DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD | 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 |

openssl命令进行加/解密

1 指定密钥和初始向量

$ openssl enc -aes-128-cbc -in in.txt -out out.txt -K 12345678901234567890 -iv 12345678

将in.txt文件的内容进行加密后输出到out.txt中。这里通过-K指定密钥,-iv指定初始向量。注意AES算法的密钥和初始向量都是128位的,这里-K和-iv后的参数都是16进制表示的,最大长度为32。 即-iv 1234567812345678指定的初始向量在内存中为 | 12 34 56 78 12 34 56 78 00 00 00 00 00 00 00 00 |。

通过-d参数表示进行解密 如下

$ openssl enc -aes-128-cbc -in in.txt -out out.txt -K 12345678901234567890 -iv 12345678 -d

表示将加密的in.txt解密后输出到out.txt中

2 通过字符串密码加/解密

$ openssl enc -aes-128-cbc -in in.txt -out out.txt -pass pass:helloworld

这时程序会根据字符串"helloworld"和随机生成的salt生成密钥和初始向量,也可以用-nosalt不加盐。

C中调用openssl库

下面这个是C语言调用openssl的例子,来自openssl官方文档

 int do_crypt(FILE *in, FILE *out, int do_encrypt)
 {
     /* Allow enough space in output buffer for additional block */
     unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
     int inlen, outlen;
     EVP_CIPHER_CTX *ctx;
     /*
      * Bogus key and IV: we'd normally set these from
      * another source.
      */
     unsigned char key[] = "0123456789abcdeF";
     unsigned char iv[] = "1234567887654321";

     /* Don't set key or IV right away; we want to check lengths */
     ctx = EVP_CIPHER_CTX_new();
     EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL,
                       do_encrypt);
     OPENSSL_assert(EVP_CIPHER_CTX_key_length(ctx) == 16);
     OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 16);

     /* Now we can set key and IV */
     EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, do_encrypt);

     for (;;) {
         inlen = fread(inbuf, 1, 1024, in);
         if (inlen <= 0)
             break;
         if (!EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, inlen)) {
             /* Error */
             EVP_CIPHER_CTX_free(ctx);
             return 0;
         }
         fwrite(outbuf, 1, outlen, out);
     }
     if (!EVP_CipherFinal_ex(ctx, outbuf, &outlen)) {
         /* Error */
         EVP_CIPHER_CTX_free(ctx);
         return 0;
     }
     fwrite(outbuf, 1, outlen, out);

     EVP_CIPHER_CTX_free(ctx);
     return 1;
 }

do_encrypt为1时加密,为0时解密。

需要注意的在调用EVP_CipherUpdate时,EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, inlen)这里outbuf的长度必须要超过inlen + EVP_MAX_BLOCK_LENGTH。 这是填充的影响,AES-128-CBC加密时末尾会有1~16字节的填充。解密时,有时候在调用EVP_CipherFinal_ex之前无法确定是否密文已经结束。如这里每次从文件中读入1024个字节,调用EVP_CipherUpdate解密时,对最后的16个字节,可能有部分是填充,解密时需要去掉,为此这里只返回1008个字节,outlen为1008,剩余16个字节的数据保存下来。再读入1024个字节进行解密时,便可能返回1024+16个字节,如果outbuf的长度不够,便会发生内存越界。 所以函数声明变量时,unsigned char inbuf[1024]; unsigned char outbuf[1024+EVP_MAX_BLOCK_LENGTH];的原因(这这里数据块长度为16个字节)。

另外,这里使用密钥01234567890abcdeF,对应的openssl命令行操作时-K 30313233343536373839616263646546。因为字符0的ASCII码为0x30,以此类推,同样 初始向量1234567887654321,对应openssl命令的参数-iv 31323334353637383837363534333231。下面的命令与上面的函数效果相同。

$ #加密
$ openssl enc aes-128-cbc -in in.txt -out out.txt -K 30313233343536373839616263646546 -iv 31323334353637383837363534333 -e
$ #解密
$ openssl enc aes-128-cbc -in in.txt -out out.txt -K 30313233343536373839616263646546 -iv 31323334353637383837363534333 -d

如果是用openssl命令加密文件,在其他程序中读取解密的话,这里就需要额外注意。

也可以通过int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);取消填充,这时明文长度必须要16的整数倍。

© 著作权归作者所有

qlee

qlee

粉丝 10
博文 33
码字总数 42906
作品 0
闵行
程序员
私信 提问
Android外部文件加解密及应用实践

有这样的应用场景,当我们把一些重要文件放到asset文件夹中时,把.apk解压是可以直接拿到这个文件的,一些涉及到重要信息的文件我们并不想被反编译拿去,这个时候需要先对文件进行加密,然后...

C6C
2018/05/08
0
0
看完秒懂对称加密、非对称加密、数字签名

对称加密算法 对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,同时解密密钥也可以从加密密钥中推算出来。而在大...

yushiwh
2018/07/11
0
0
用openssl对文件加密及解密

Openssl是一个开源的用以实现SSL协议的产品,它主要包括了三个部分:密码算法库、应用程序、SSL协议库。Openssl实现了SSL协议所需要的大多数算法。 下面我将单介绍使用Openssl进行文件的对称...

独钓渔
2014/07/24
496
0
c# .NET RSA结合AES加密服务端和客户端请求数据

这几天空闲时间就想研究一下加密,环境是web程序,通过js请求后台返回数据,我想做的事js在发送请求前将数据加密,服务端收到后解密,待服务端处理完请求后,将处理结果加密返回给客户端,客...

金同学
2018/08/02
0
0
PHP 迁移 Mcrypt 至 OpenSSL 加密算法详解

对称加解密算法中,当前最为安全的是 AES 加密算法(以前应该是是 DES 加密算法),PHP 提供了两个可以用于 AES 加密算法的函数簇:Mcrypt 和 OpenSSL。 其中 Mcrypt 在 PHP 7.1.0 中被 Depr...

big_cat
03/03
157
0

没有更多内容

加载失败,请刷新页面

加载更多

学习记录(day05-标签操作、属性绑定、语句控制、数据绑定、事件绑定、案例用户登录)

[TOC] 1.1.1标签操作v-text&v-html v-text:会把data中绑定的数据值原样输出。 v-html:会把data中值输出,且会自动解析html代码 <!--可以将指定的内容显示到标签体中--><标签 v-text=""></......

庭前云落
41分钟前
5
0
VMware vSphere的两种RDM磁盘

在VMware vSphere vCenter中创建虚拟机时,可以添加一种叫RDM的磁盘。 RDM - Raw Device Mapping,原始设备映射,那么,RDM磁盘是不是就可以称作为“原始设备映射磁盘”呢?这也是一种可以热...

大别阿郎
今天
9
0
【AngularJS学习笔记】02 小杂烩及学习总结

本文转载于:专业的前端网站☞【AngularJS学习笔记】02 小杂烩及学习总结 表格示例 <div ng-app="myApp" ng-controller="customersCtrl"> <table> <tr ng-repeat="x in names | orderBy ......

前端老手
昨天
13
0
Linux 内核的五大创新

在科技行业,创新这个词几乎和革命一样到处泛滥,所以很难将那些夸张的东西与真正令人振奋的东西区分开来。Linux内核被称为创新,但它又被称为现代计算中最大的奇迹,一个微观世界中的庞然大...

阮鹏
昨天
16
0
【Medium 万赞好文】ViewModel 和 LIveData:模式 + 反模式

原文作者: Jose Alcérreca 原文地址: ViewModels and LiveData: Patterns + AntiPatterns 译者:秉心说 View 和 ViewModel 分配责任 理想情况下,ViewModel 应该对 Android 世界一无所知。...

秉心说
昨天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部