openssl加密解密指令_openssl命令aes加密和解密
openssl命令aes加密和解密
⽇期:2014-11-12 10:41:25
最后更新⽇期:2017-07-06 10:00:10
【技术】
man openssl查看openssl的功能:
[code lang="cpp"]
o Creation and management of private keys, public keys and parameters
o Public key cryptographic operations
o Creation of X.509 certificates, CSRs and CRLs
o Calculation of Message Digests
cipher命令o Encryption and Decryption with Ciphers
o SSL/TLS Client and Server Tests
o Handling of S/MIME signed or encrypted mail
o Time Stamp requests, generation and verification
[/code]
openssl⼯具功能如上诉,有些功能也是在实际⼯作中慢慢积累。最后两项功能,笔者就没有使⽤过。
1.openssl aes加密和解密
这⾥着重与openssl c api和python 的api能够相互转化。说⽩了都是同⼀套库。原始的aes加密和解密,key的长度与block⼤⼩⼀致。openssl库默认的aes加密⽅式如下:
[code lang="cpp"]
AES_KEY aeskey;
unsigned char userKey[16];
AES_set_encrypt_key((uint8 *)userKey, bits=128, &aeskey);
AES_encrypt(unsigned char * in, unsigned char *out, &aeskey);
[/code]
这种块的分组加密模式为ecb模式,常见的分组模式为电⼦密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)。实际上openssl封装了更⾼层的evp_*函数调⽤。給⼀个函数名称EVP_EncryptInit,便于查看man⼿册。
前⾯的userKey可以这样赋值:
[code lang="cpp"]
unsigned char userKey[16]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
[/code]
等效的openssl命令为:
[code lang="cpp"]
$ echo -ne 'hello world\0\0\0\0\0' | openssl enc -aes-128-ecb -nosalt -nopad -K
'000102030405060708090A0B0C0D0E0F' | xxd
0000000: 1281 34b4 5a7c 03ad 6dc6 5a47 97a0 77f2 ..4.Z|..m.ZG..w.
[/code]
-K表⽰hex⽅式输⼊key,使⽤nosalt⽅式,否则会有前缀。另外若使⽤-k参数,表⽰的意思,即要将-k指定的passphrase(密码),按照-md指定的⽅式计算报⽂摘要作为key。
[code lang="cpp"]
$ echo -ne 'hello world\0\0\0\0\0' | openssl enc -aes-128-ecb -nosalt -nopad -k '0123456789abcdef' -md md5 | xxd
0000000: 54a7 f164 6051 c41e 2ca0 f777 d50f 68f5 T..d`Q..,..w..h.
[/code]
openssl命令-p参数可以打印实际使⽤的key,打印该key放到cpp⽂件⾥⾯,加密后值⼀样。
2.AES填充⽅式(padding)
AES是分块计算,当数据内容不⾜,16字节(128 bit aes),24字节(192 bit aes),32字节(256 bit aes),不⾜部分就需要填充。wiki上⾯列举填充⽅式有如下⼏种:
1.ANSI X.923
不⾜部分填充0,最后⼀字节为填充字节数。如下⾯8字节的块,需要填充4字节时:
... | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 04 |
2.ISO 10126
不⾜部分填充随机数字,最后⼀字节为填充字节数。如下⾯8字节的块,需要填充4字节时:
... | DD DD DD DD DD DD DD DD | DD DD DD DD BC DA EF 04 |
3.PKCS7与PKCS5
不⾜部分填充为需要填充字节数。若数据⼤⼩是分块⼤⼩N的倍数时,则增加⼀个全为N的分块。如下⾯8字节的块,需要填充4字节时:
... | DD DD DD DD DD DD DD DD | DD DD DD DD 04 04 04 04 |
4.ISO/IEC 7816-4
不⾜的部分,⾸先填充⼀个0x80,剩余部分全为0。如下⾯8字节的块,需要填充4字节时:
... | DD DD DD DD DD DD DD DD | DD DD DD DD 80 00 00 00 |
要求数据内容本⾝不包含0x80
4.Zero padding
不⾜部分全部填充0。如下⾯8字节的块,需要填充4字节时:
... | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 00 |
这种⽅法不能区分数据内容本⾝末尾包含0的情况,因⽽也不是标准的填充⽅式。
openssl aes加密时,若指定nopad,则要求数据本⾝是分块⼤⼩的整数倍。否则根据openssl⼿册描述,使⽤标准填充⽅式,验证这种⽅式即为PKCS7。
[code lang="cpp"]
[root@localhost ~]# echo -ne 'hello\xb\xb\xb\xb\xb\xb\xb\xb\xb\xb\xb' | openssl enc -aes-128-ecb -nosalt -k "012" -md md5 -nopad | xxd
0000000: c9c3 ee5a b1fa ed01 d91d 30cd 56e5 c2e7 ...Z......
[root@localhost ~]# echo -ne 'hello' | openssl enc -aes-128-ecb -nosalt -k "012" -md md5 | xxd
0000000: c9c3 ee5a b1fa ed01 d91d 30cd 56e5 c2e7 ...Z......
[/code]
题外话,对于nginx的lua-resty-string-0.09模块,没有指定padding的参数,使⽤的也是PKCS7填充⽅式。nginx aes模块是把password的md5作为Key。与openssl相互转化⽰例:
[code lang="cpp"]
location /t1 {
content_by_lua '
local aes = require "resty.aes"
local str = require "resty.string"
local aes_default = aes:new("FUCKCODE",nil,
aes.cipher(128,"ecb"),aes.hash.md5,1)
local encrypted = aes_default:encrypt("hello world")
--ngx.say("AES-128 ECB md5: ", _hex(encrypted))
local decrypted = aes_default:decrypt(encrypted)
ngx.say(encrypted)
--ngx.say(decrypted == "hello world")
';
}
[/code]
解密:
[code lang="cpp"]
[root@localhost ~]# curl "10.10.31.230:81/t1 >81.bin
[root@localhost ~]#dd if=81.bin of=81_16.bin bs=16 count=1
[root@localhost ~]# openssl enc -d -aes-128-ecb -nopad -nosalt -k "FUCKCODE" -iv "" -in 81_16.bin -out des_out_t1.bin
[root@localhost ~]# xxd des_out_t1.bin
0000000: 6865 6c6c 6f20 776f 726c 6405 0505 0505
[/code]
4.python aes加密和解密
实际⼯作中python的接⼝也⽐较常⽤,如下:
[code lang="cpp"]
from Crypto.Cipher import AES
import struct,binascii
aeskey = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" aes_tool = w(aeskey , AES.MODE_ECB)
resp_data="hello world\0\0\0\0\0"
plain_txt = pt(resp_data)
print(binascii.b2a_hex(plain_txt))
[/code]
openssl功能后续补充,其它加密和解密⽅式类似。
参考:
1.aes填充⽅式
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论