[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` [toc] ## 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 ``` shell 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 ``` shell 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 ```shell 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 ``` shell 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. ```shell 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](https://onlinestringtools.com/convert-string-to-ascii) 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 | {%gist d428d7bc093fbf67c6032bf5093f8695%} ## 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. ```shell 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 ```shell 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