I'm working on an application that needs to decrypt a file by mbedtls which is encrypted by openssl. Currently, the decryption is not working. After investigation I've found that I cannot create the same encrypted file by using the two frameworks. What is the difference between the two encryption approaches?
Openssl:
-> ✗ cat message
hello world
-> ✗ openssl aes-256-ecb -nosalt -K 6261757363680000000000000000000000000000000000000000000000000000 -in message -out koekoek.bin
-> ✗ xxd koekoek.bin
00000000: 68e1 1f1e 8397 a33e ddea 5c4d 3192 11ab h......>..\M1...
MbedTLS:
(gdb) p (void)memset(decrypt_output, 0, 16)
$63 = void
(gdb) p sprintf(decrypt_output, "hello world")
$64 = 11
(gdb) p/x key
$65 = {0x62, 0x61, 0x75, 0x73, 0x63, 0x68, 0x0 <repeats 26 times>}
(gdb) p mbedtls_aes_setkey_enc(&aes, key, 256)
$66 = 0
(gdb) p mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, decrypt_output, decrypt_output)
$67 = 0
(gdb) p/x decrypt_output
$68 = {0x1b, 0x7c, 0x4d, 0x41, 0xaf, 0xa4, 0x65, 0x7f, 0x56, 0x39, 0x95, 0x2a, 0x21, 0x32, 0x10, 0xab}
(gdb)
The following openssl command produces the same result as your mbedtls script:
echo -ne "hello world\0\0\0\0\0" | openssl aes-256-ecb -nopad -K 6261757363680000000000000000000000000000000000000000000000000000 | xxd -p
produces:
1b7c4d41afa4657f5639952a213210ab
Note that the input string is padded up to 16 characters in length (i.e. the length of one AES block) using null (\0) characters, to match what mbedtls does by default (the -e option is needed with echo to allow null characters in the input). Also, the -n option is used with echo so that echo does not append a newline character to the input. Finally, the -nopad option is used with the openssl command, so that openssl does not add an additional block of pkcs#7 padding.
Related
I'm trying too encrypt and decrypt using pkcs#11-tool
echo 'Hello word !' | openssl pkeyutl -encrypt -pubin \
-inkey pub.pem \
-pkeyopt rsa_padding_mode:oaep \
-pkeyopt rsa_oaep_md:sha512 \
-pkeyopt rsa_mgf1_md:sha512 \
-out encrypted.data
This work find but trying to decrypt it fail
pkcs11-tool --module /usr/local/lib/softhsm/libsofthsm2.so --decrypt \
--mechanism RSA-PKCS-OAEP \
--input-file encrypted.data \
--label keyp \
--hash-algorithm SHA512 --pin Jojo
I'm having this error :
Using slot 0 with a present token (0x607f2e7f)
Using decrypt algorithm RSA-PKCS-OAEP
OAEP parameters: hashAlg=SHA512, mgf=MGF1-SHA512, source_type=0, source_ptr=(nil), source_len=0
error: PKCS11 function C_DecryptInit failed: rv = CKR_ARGUMENTS_BAD (0x7)
Aborting.
I'm following this tutorial : https://docs.nitrokey.com/nethsm/guides/pkcs11_with_pkcs11-tool and can't what wrong.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
I want to decrypt AES encrypted data with openssl command.
Encrypted data: GD5YV2naJZ/x3mQnfictWQ== (base64 encoded)
Key: uHe2MCmggLlugpGBiMVuXTck7OT8Nk8g
Cipher: AES-256-CBC
IV: LNP8U7pc6GjxzxAtgw4s3A== (base64 encoded)
Follow these steps:
$ echo GD5YV2naJZ/x3mQnfictWQ== | openssl base64 -d > data.enc
$ iv=$( echo LNP8U7pc6GjxzxAtgw4s3A== | openssl base64 -d | xxd -p | tr -d '\n' )
$ echo $iv
2cd3fc53ba5ce868f1cf102d830e2cdc
$ key=$( echo uHe2MCmggLlugpGBiMVuXTck7OT8Nk8g | xxd -p | tr -d '\n' )
$ echo $key
754865324d436d67674c6c7567704742694d56755854636b374f54384e6b38670a
$ openssl aes-256-cbc -d -in data.enc -K $key -iv $iv
s:4:"Test";
With -base64 option, the decrypt command can directly use base64 encoded data as the input:
$ echo GD5YV2naJZ/x3mQnfictWQ== | openssl aes-256-cbc -d -base64 -K $key -iv $iv
s:4:"Test";
Please follow the encryption and decryption of the string according to its documentation and follow the step as well:
to decrypt a string use the following:
Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;
try {
$decrypted = Crypt::decryptString($encryptedValue);
} catch (DecryptException $e) {
//
}
for encryption use:
use Illuminate\Support\Facades\Crypt;
Crypt::encryptString($request->token)
I want to decrypt large AES encrypted data:
Encrypted data: 7dS560FiDJvUji7c+ky/9nQp+HwK3SEOkY4zefqlFuEyF2/vevrv8K4GJNr2zxD7+j28RK97LmaHjwY9F+/feO6T2DAQuJQsT3wp/fKCPyErwZggsE+ufzvEJZK/XObR8CdbBe8EGZC//JsuMo7MV6SSe267jp4U2iIz4xIFxUlFVy9QcjTr6AUJZdVogedreBgy3/q/isAqOvwoHuj74MV5gkfaXWvmqESjMF4s5wMsYmS1WuBWOR6rw+TSwuL52CiVC5arHuJJEKuodO58bJ+1Ip9uelUIOETswiZmZB6gpTkbos7ij0BpJregejT+9vsDO1tB7+QpByMqeeEbEiSp4N833Z29WmVmy+HpxdZvOPIJ2pyelVhRVPPs/V7VREs4v8/e3X1jR0saA1sSyKYNgIGZUWaQTJwBNi87IPkGiUtyhPnrrKh+BighshJi+Jd+s3+sTYM5CaADvaGhm3wx96rBQi2So+NmFcm5cQa4jRA4S8sLGHmniUO0iiEcxQ2FvlGt+0PBqdbCPewBgOHdjpBUYjs1oR4pV5VjbjTfuIh75G7TS6TZT/gMewJXOXPw88zsSgjXVjRK0obOXaJBKABJ8AqKbKULWHoeMuWW4OdiSZ7mNVt6N40LK/u12vpqWU7Wt5XbSeE3arJPjljEV7WhafKvIOHFx+cK0wB9LQnFUrx/FTLL5HDDEkhnVkm02vxXSFKDwP36VgQnPpvOnY5fbJUTyjnwJcO8I9/H1hYwzPRhos2eNAdHZ3aMysU8zSobwUVto9GnQrvVmVURFyEX6fwifkrf2DTfCsDNSsHt4DLCtsszABKTwTezUoBesNkndk/Qkcd13GEZjTHoyP2tLp85nYwbwI6P+yr1jeu9v3ocN5p0LWPXdwlyTo55WeYkGzlJLsM6d9sut1qlcyQ2AZ536+eYFAIURJkmSexwfbdRebwckvqURRO3a55WCbLxVARKDHnyfculr/ndwyZF7J0RX4G1KcwSgfRdnBpUCkpGeQRImv5Ry5RYXwp5XfKQDrGTCEhV3XtDBD4b2eTxw4KwgJUq9T6IQjNNyPyDwM5AFxS2Y+4wAA0PA2iADfVe3kZrOKYpZvVn0Q== (base64 encoded)
Key: uHe2MCmggLlugpGBiMVuXTck7OT8Nk8g (base64 encoded)
Cipher: AES-256-CBC
IV: LNP8U7pc6GjxzxAtgw4s3A== (base64 encoded)
I try to use this command for it:
openssl aes-256-cbc -d -in data.enc -out data.dec -K $key -iv $iv
In $key and $iv i decoded from encoded values this way
iv=$( cat response.json | jq .iv -r | openssl base64 -d | xxd -p | tr -d '\n' )
But i have crashed data like this
^GÌ<8a>û)F"PEi~^K±jÔ^AcWSM
23NDwSOqovXSFGNfy3WatkCreYRd7kcWSM";
I'm trying to encrypt a simple string such as "Hello World!" via Crypto++, and decrypt it via Crypto++ succeed. but I got an error when decrypt Crypto++ encrypted result via OpenSSL command.
My C++ code:
#include <iostream>
#include <aes.h>
#include <base64.h>
#include <modes.h>
std::string aes_encrypt(std::string key, std::string plain)
{
std::string result;
CryptoPP::ECB_Mode<CryptoPP::AES>::Encryption ecb_encryptor((byte *)key.c_str(), CryptoPP::AES::MAX_KEYLENGTH);
auto encryptor = new CryptoPP::StreamTransformationFilter(ecb_encryptor,
new CryptoPP::Base64Encoder(new CryptoPP::StringSink(result), false),
CryptoPP::StreamTransformationFilter::ZEROS_PADDING);
CryptoPP::StringSource(plain, true, encryptor);
return result;
}
std::string aes_decrypt(std::string key, std::string cipher)
{
std::string result;
CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption ecb_decryptor((byte *)key.c_str(), CryptoPP::AES::MAX_KEYLENGTH);
auto decryptor = new CryptoPP::Base64Decoder(new CryptoPP::StreamTransformationFilter(ecb_decryptor,
new CryptoPP::StringSink(result),
CryptoPP::StreamTransformationFilter::ZEROS_PADDING));
CryptoPP::StringSource(cipher, true, decryptor);
return result;
}
int main(int argc, char **argv)
{
const char *key = "1234567890";
const char *plain = "Hello World!";
std::cout << "plain: " << plain << std::endl;
std::string cipher = aes_encrypt(key, plain);
std::cout << "cipher: " << aes_encrypt(key, plain) << std::endl;
std::cout << "plain: " << aes_decrypt(key, cipher) << std::endl;
return 0;
}
Output:
plain: Hello World!
cipher: bVgt4KsCOTULujusMJvhhw==
plain: Hello World!
OpenSSL command:
xxx#xxxdeMacBook-Pro ~ $ echo -n 'Hello World!' | openssl enc -e -aes-256-ecb -nosalt -a -A -pass pass:1234567890
7sQWFmxUUQ8DpoXh9DXS8g==
xxx#xxxdeMacBook-Pro ~ $ echo -n '7sQWFmxUUQ8DpoXh9DXS8g==' | openssl enc -d -aes-256-ecb -nosalt -a -A -pass pass:1234567890
Hello World!
Try to use OpenSSL to decrypt Crypto++ result failed:
xxx#xxxdeMacBook-Pro ~ $ echo -n 'bVgt4KsCOTULujusMJvhhw==' | openssl enc -d -aes-256-ecb -nosalt -a -A -pass pass:1234567890
bad decrypt
78710:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64.50.6/src/crypto/evp/evp_enc.c:330:
That's because you're using a different padding (Zero Padding in Crypto++ vs. PKCS#7 padding in OpenSSL) and a completely different key.
In OpenSSL, the key is derived from the password that you provide (it's called -pass after all) using the EVP_BytesToKey function.
If you want to use a proper AES key, you can use the -K commandline option to provide a Hex encoded key (should be 32, 48 or 64 characters long).
In Crypto++ you're directly passing a broken key to ecb_encryptor. AES supports keys of 16, 24 and 32 bytes length and nothing in between. But you're providing a 10 byte key and tell Crypto++ that the key is actually 32 byte long. This probably results in a random key because the remaining bytes in memory probably contain some junk values.
If you want to use the password-based encryption of OpenSSL, Crypto++ provides an implementation of OpenSSL's EVP_BytesToKey function.
Whether you decide to use an valid AES key or a password is up to you. Remember that an AES key is supposed to be randomly generated to be secure and a password must be long enough to provide any good security. I would say the password must be roughly 30% longer than the bit strength that you're going for (for 128 bit security you would need a randomly generated password of 21 characters containing uppercase, lowercase letters and digits).
Security considerations:
You should never use ECB mode. It's deterministic and therefore not semantically secure. You should at the very least use a randomized mode like CBC or CTR. It is better to authenticate your ciphertexts so that attacks like a padding oracle attack are not possible. This can be done with authenticated modes like GCM or EAX, or with an encrypt-then-MAC scheme.
How to hash a string using SHA-1 and base64 encode? I have package openssl and I can use sha1 function to has a string but I don't know how to combine sha-1 and base64 encode to my string.
For testing purpose, my string is:
HY8&V5EDJO8NYT9C2011-12-13T00:44:02ZTest123
I need to SHA-1 and base64 encode to output:
nuoiyUX6m+irC5rvB4QUSycfHGc=
Please could someone kindly advice?
As you are using the openssl package, use the following function
openssl::base64_encode(openssl::sha1(charToRaw("HY8&V5EDJO8NYT9C2011-12-13T00:44:02ZTest123")))
openssl generally operates on a file,basically stdin in a byte stream.
I am passing "HY8&V5EDJO8NYT9C2011-12-13T00:44:02ZTest123" in a form of printf, In a sequence of non-0 bytes (which may or may not form valid characters in UTF-8 or other character set/encoding).
Since the input is passed from the terminal, on a keyboard. The terminal will send corresponding characters (as written on the key label) encoded in its configured character set.
Usually, set in the current locale. You can find that by using a command "locale charmap".
We have to make sure the input is first convierted to UTF-8 and then passed to openssl. that the reason i have used icovn to convert bytes to the corresponding encoding in UTF-8.
So below command can be used to convert our string in sha1 and then base64 using openssl.
printf %s "HY8&V5EDJO8NYT9C2011-12-13T00:44:02ZTest123" | iconv -t utf-8 | openssl dgst -sha1 -binary | openssl enc -base64
$ echo nuoiyUX6m+irC5rvB4QUSycfHGc= | base64 -d | xxd -g 1
00000000: 9e ea 22 c9 45 fa 9b e8 ab 0b 9a ef 07 84 14 4b ..".E..........K
00000010: 27 1f 1c 67
And:
$ echo -n "HY8&V5EDJO8NYT9C2011-12-13T00:44:02ZTest123" | openssl sha1
(stdin)= 9eea22c945fa9be8ab0b9aef0784144b271f1c67
And:
$ cat test.c
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
int main()
{
unsigned char ibuf[] = "HY8&V5EDJO8NYT9C2011-12-13T00:44:02ZTest123";
unsigned char obuf[20];
SHA1(ibuf, strlen(ibuf), obuf);
int i;
for (i = 0; i < 20; i++) {
printf("%02x ", obuf[i]);
}
printf("\n");
return 0;
}
And then:
$ gcc -I /usr/local/include/ test.c /usr/local/lib/libcrypto.a -o test.exe
$ ./test.exe
9e ea 22 c9 45 fa 9b e8 ab 0b 9a ef 07 84 14 4b 27 1f 1c 67
Maybe a little bit late, but try
$ echo -n "HY8&V5EDJO8NYT9C2011-12-13T00:44:02ZTest123" | openssl dgst -binary -sha1 | openssl enc -base64
This will:
Echo the string to the pipe
openssl will digest the string using SHA1 algorithm and pipe it
openssl will encode the resulting digested string from step 2 into a new string using base64 algorithm
And it will be echoed back to you.