Try   HackMD

[Development] AES encryption/decryption through OpenSSL API and binary respectively

tags: development, C, tool, linux, AES, CBC, ECB, OpenSSL, openssl, openssl API, openssl binary, hexdump, od, xxd

Overview

In this note, on one hand, I will show how to use the openssl binary to encrypt and decrypt a file. On the other hand, I will demo how to encrypt a file through openssl binary and decrypt it through openssl API in c code.

Environment

In this case, I encrypt a file in a x86-based system, and decrypt it in a mips-based system which is a switch here.

  • x86-based Host for encryption
Tomas# uname -a
Linux 4.15.0-99-generic #100-Ubuntu SMP Wed Apr 22 20:32:56 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux 

Tomas# openssl version                                                       
OpenSSL 1.1.1  11 Sep 2018
  • mips-based for decryption
Switch# uname -r
Linux Switch 3.18.24 #1 Thu Jun 11 10:40:48 CST 2020 mips GNU/Linux

openssl version v 1.1.1.1 2015/04/28

Openssl binary usage

openssl help

Tomas# openssl help
Standard commands
asn1parse         ca                ciphers           cms               
crl               crl2pkcs7         dgst              dhparam           
dsa               dsaparam          ec                ecparam           
enc               engine            errstr            gendsa            
genpkey           genrsa            help              list              
nseq              ocsp              passwd            pkcs12            
pkcs7             pkcs8             pkey              pkeyparam         
pkeyutl           prime             rand              rehash            
req               rsa               rsautl            s_client          
s_server          s_time            sess_id           smime             
speed             spkac             srp               storeutl          
ts                verify            version           x509              

Message Digest commands (see the `dgst' command for more details)
blake2b512        blake2s256        gost              md4               
md5               rmd160            sha1              sha224            
sha256            sha3-224          sha3-256          sha3-384          
sha3-512          sha384            sha512            sha512-224        
sha512-256        shake128          shake256          sm3               

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
aes-256-cbc       aes-256-ecb       aria-128-cbc      aria-128-cfb      
aria-128-cfb1     aria-128-cfb8     aria-128-ctr      aria-128-ecb      
aria-128-ofb      aria-192-cbc      aria-192-cfb      aria-192-cfb1     
aria-192-cfb8     aria-192-ctr      aria-192-ecb      aria-192-ofb      
aria-256-cbc      aria-256-cfb      aria-256-cfb1     aria-256-cfb8     
aria-256-ctr      aria-256-ecb      aria-256-ofb      base64            
bf                bf-cbc            bf-cfb            bf-ecb            
bf-ofb            camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  
camellia-192-ecb  camellia-256-cbc  camellia-256-ecb  cast              
cast-cbc          cast5-cbc         cast5-cfb         cast5-ecb         
cast5-ofb         des               des-cbc           des-cfb           
des-ecb           des-ede           des-ede-cbc       des-ede-cfb       
des-ede-ofb       des-ede3          des-ede3-cbc      des-ede3-cfb      
des-ede3-ofb      des-ofb           des3              desx              
rc2               rc2-40-cbc        rc2-64-cbc        rc2-cbc           
rc2-cfb           rc2-ecb           rc2-ofb           rc4               
rc4-40            seed              seed-cbc          seed-cfb          
seed-ecb          seed-ofb          sm4-cbc           sm4-cfb           
sm4-ctr           sm4-ecb           sm4-ofb   

openssl aes-128-ecb help

Tomas# openssl aes-128-ecb -help                                             
Usage: aes-128-ecb [options]
Valid options are:
 -help               Display this summary
 -ciphers            List ciphers
 -in infile          Input file
 -out outfile        Output file
 -pass val           Passphrase source
 -e                  Encrypt
 -d                  Decrypt
 -p                  Print the iv/key
 -P                  Print the iv/key and exit
 -v                  Verbose output
 -nopad              Disable standard block padding
 -salt               Use salt in the KDF (default)
 -nosalt             Do not use salt in the KDF
 -debug              Print debug info
 -a                  Base64 encode/decode, depending on encryption flag
 -base64             Same as option -a
 -A                  Used with -[base64|a] to specify base64 buffer as a single line
 -bufsize val        Buffer size
 -k val              Passphrase
 -kfile infile       Read passphrase from file
 -K val              Raw key, in hex
 -S val              Salt, in hex
 -iv val             IV in hex
 -md val             Use specified digest to create a key from the passphrase
 -iter +int          Specify the iteration count and force use of PBKDF2
 -pbkdf2             Use password-based key derivation function 2
 -none               Don't encrypt
 -*                  Any supported cipher
 -rand val           Load the file(s) into the random number generator
 -writerand outfile  Write random data to the specified file
 -engine val         Use engine, possibly a hardware device

Encryption by binary and decrpytion by binary

In this case, it is intuitive. The command is mostly the same including parameters like -K, -k, -iv, -nosalt, -pbkdf2, -iter and so on. The differences are -d/-e and -in/-out.

I gave an example below.

Tomas# cat org.txt
thisismytestforaesencanddecsadfsadf

Tomas# openssl aes-128-ecb -e -k aaaaaaaa -p -nosalt -pbkdf2 -in org.txt -out cypher.txt
key=35D447AD8E76F1BFB40F12EAF216ABEB
Tomas# cat cypher.txt
+-~=)Rb}]pP\6;:%3(߁
                   X%

Tomas# openssl aes-128-ecb -d -k aaaaaaaa -p -nosalt -pbkdf2 -in cypher.txt -out plain.txt
key=35D447AD8E76F1BFB40F12EAF216ABEB
Tomas# cat plain.txt
thisismytestforaesencanddecsadfsadf

Tomas# openssl aes-128-ecb -d -K 35D447AD8E76F1BFB40F12EAF216ABEB -p -nosalt -pbkdf2 -in cypher.txt -out plain2.txt
key=35D447AD8E76F1BFB40F12EAF216ABEB
Tomas# cat plain2.txt
thisismytestforaesencanddecsadfsadf

Encryption by binary and decrpytion by API

In this case, I encrypt a file by openssl binary and decrypt it by API imported in my code.
The key point here is the key/iv in C code are strings while in parameter are hex. Therefore, we have to convert the key/iv in C code to hex digits as a parameter when launching openssl binary. This can be done through an online tool here or others.

For instance,

  • in C code, assume
    • key = mybiggg_only_123
    • iv = thisisxoperation (for CBC)
  • in the parameter of -K
    • key = 6d7962696767675f6f6e6c795f313233
    • iv = 746869736973786f7065726174696f6e (for CBC)

Encryption

openssl aes-128-ecb -e -K 6d7962696767675f6f6e6c795f313233 -p -in org.txt -out cypher.txt 

openssl aes-128-cbc -e -K 6d7962696767675f6f6e6c795f313233 -iv 746869736973786f7065726174696f6e -p -in org -out cypher2.txt

Decryption

Here, we just demo simple ECB.

Below gist shows:

File Name Description
AES_example.c The source code for demo
Makefile For build binary
org.txt The original plaint text
gen_cypher.sh The command to generate cypher text
plain.txt The outcome of aes_example

Tools to dump hex

When we implement features like AES encryption/decryption or MD5/SHA checksum in a file, we usually need to deubg it to check whether our encrypting, decrypting or checksum calculating are correct. So, we need some tools to inspect it.

We can utilize tools such as hexdump, od, and xxd to dump hex values in a file or binary.

Below shows some examples of them.

Tomas# hexdump uImage | head -n 2
0000000 0527 5619 d0bb 0c65 005f b69d 1e00 404c
0000010 0080 0000 2780 50a0 cac5 e513 0505 0102

Tomas# od -x  uImage | head -n 2
0000000 0527 5619 d0bb 0c65 005f b69d 1e00 404c
0000020 0080 0000 2780 50a0 cac5 e513 0505 0102

Tomas# xxd  uImage | head -n 2
00000000: 2705 1956 bbd0 650c 5f00 9db6 001e 4c40  '..V..e._.....L@
00000010: 8000 0000 8027 a050 c5ca 13e5 0505 0201  .....'.P........

Tomas#  hexdump -C uImage | head -n 2
00000000  27 05 19 56 bb d0 65 0c  5f 00 9d b6 00 1e 4c 40  |'..V..e._.....L@|
00000010  80 00 00 00 80 27 a0 50  c5 ca 13 e5 05 05 02 01  |.....'.P........|

Annex

Build openssl shared libaray

Tomas# git clone git://git.openssl.org/openssl.git
Tomas# cd openssl
Tomas# git checkout OpenSSL_1_1_1-stable
Tomas# ./config -fPIC -shared
Tomas# make -j8
Tomas# cp libcrypto.so ../your_destination/

Reference

https://onlinestringtools.com/convert-string-to-ascii
http://aes.online-domain-tools.com/
https://emn178.github.io/online-tools/md5_checksum.html
https://my.oschina.net/u/2539854/blog/1559531
https://stackoverflow.com/questions/2537271/compile-openssl-with-the-shared-option
http://www.361way.com/hexdump/749.html