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.
Related
i'm trying to connect esp32 to firestore but an error appear on the serial monitor
Token info: type = OAuth2.0 access token, status = error
Token error: code: -116, message: mbedTLS, mbedtls_pk_parse_key: PK - Invalid key tag or value
i'm using source code from https://github.com/mobizt/Firebase-ESP-Client/blob/main/examples/Firestore/ImportDocuments/ImportDocuments.ino
Most likely you've not provided the private key string correctly (TLS libraries are rather picky about that), or the private key is not in correct format.
E.g. this is how you generate a 2048 bit RSA keypair in PKCS8 format (which is what the sample code appears to use):
$ ssh-keygen -t rsa -b 2048 -m PKCS8 -f testkey
This is how you add the resulting private key as a multiline raw string literal in C++:
const char PRIVATE_KEY[] = R"(-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhhA52G0UQGFk5
+WDGpWXgVHR6Bjpyq81HZ0SI9PQYTZa87b4qOysL8QkpeXiUR5Ltza1A5ceLERfy
2fpwhLIdHDmFN9dYQIN7ODf8dPRFVPT9ABegHDGzNWQJBuDe9ffVfF8DYeSlo7iq
vKUSeL2IpbTFn7Ccard68Wee3GueIm0GVi6V/HKhJYT4Cq6Fp8g/xVMdwAD6AFR8
8vBH1FERJn+6U89xdgewnjrw69jhlctziIdDxANedqTX/aEkchKcFhhmXehwsFfn
3gdToJBu0fClaTUvm0tYMRLaoUfAQ9t6J9TtPkA3ZZFzge7FZGl3lpFd6NOiiiQD
Fi9NLXx7AgMBAAECggEANNV1deIpqf2qWdS9AY0acxYWO8hdxSPO8h2Vhuisj00O
NbEVTluSWDfeR6M3xrWGDMSVBJFQ0JnunGzJKbdM61kDeNx+TSTAKQwgwbq8x8mB
pAxzfIVed3fYueysnk/OAmwi7m3u3Yef6hBMNCmpbew0j+A7xkmSNvF7r1JAvEkv
wnRy4GY9+39HHotF0T2BofdmxA0i5hS7NQc5AxJ+O9xVB4qoUCoPDXsOXfQoGURe
ugR7ANSONwIbnfSkcTanoMeqaQeSpLe+cNlBKTG+ofQyOsM2vSbPndUNx+CerLPe
Jya+/owBgYCTeOG+E+Bs05God/y/HuX5hUJVHSQHIQKBgQD7Z9XFf6Ecs8oGHx6g
D4qWNxLolB9Ls6W9MkXrrTcPMWQJIbYM2RxNLVjdArVLDT7yUHUH/KWx/Qrd9x5P
g8H8htO2vSHJRBpFbxL5wYudsh6G38GOs65OEcjKMWryzet44bRPe9zkULbfqiwy
5KOyi4VoUc63HeiKTJbHaTwWaQKBgQDloxmU22G7Vno7BhmReH4veZ+yV2jnX8Uc
cp4ciq7XqPZNUMKTskmrLl6Lw9I2xY8ahdP0kYWB6CKJr9DF8TN09n4NN2yLz89o
mHowHCdsyjE51l7lmkdHSxCOVt+Wt4vsoegZAydm8mtAfA0W63tgMDgKpCyqtn/H
vl6v08jHQwKBgQDwtO48doKvlIRtcAZGghrS0FBOVuPP+2VIzIWdrO72oPeCtsAz
dPxf+HcIxLsH7NrD7rzetMuAqyJoe16OCz0Ep6K1aEidB5OPv1WPw/wFNLF9uWb9
VpQhM23oCYC4kOhPiOq234UTJSSy6Z//6mHBZUyKISmmsgAfykzjCKL7YQKBgDNQ
qCXIhGVtpLDN4ybLyz7mqdYbjFiv4QdDYau1He8ZVbjfRCvnGmlDWmNXJgGRUjI2
F7A+WJw3+IfWHwwsozgO4QopCXuQu6N+90cK85Bu+mMXUWtzd1wqHRABv8MZTw5Y
+9mjB8oMgAUP84jcpFxRSiSunUCkuZc0JkqaQ/KrAoGAYxtl+555GpXK9eLfrVOG
02czqaXssGXIi31aGTICy7Esk8OgaG+pd4brcICeYE/CQ6gDjt6m/dHcw+DFmeFX
nVDHCIIDB9SeHM0Z3wZi/JruCtoB6vTxhA5lA9QeI4TpZvYXQkuerRUzRvhxyzkV
PrYun0MrVLxiiwezSTxlyGw=
-----END PRIVATE KEY-----
)";
I try to deploy a datapower inside IPC with the following parameter
{
"ibm-datapower-dev": {
"name": "ibm-datapower-dev",
"crypto.frontsideCert": "-----BEGIN CERTIFICATE REQUEST----- MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAK2cJ7rtqGPsFoFNLjOQ08knGO429u+EdIEPiXvc nvumhIoSmOquUOzyIOqPCY35Wso2EjS97dH3Qa+X8Qo8L6FfmWDBn4C6RWVPxxh1 a2P0TM1eSzPP/bVU0yghgdgPkU6jYfA0OmnBN3KOHl39gc86cI8tXUxstnlACzv+ me1RKmvMfy+IE3C0qBvvPjhNjIU4vx9OJ/DaxMh2shJxHlt718mZTCy/fAqE5bc5 19Atxy7aPD9LFWQ6/mGbnLzH8l4MqrZYFkVkZx8h3uYt3eyN0co4FicBuGtgs97s VcpZz9tC2yFEi25Iql+AdGuaK+hMNU2pF5GdNaARlyLjemECAwEAAaAAMA0GCSqG SIb3DQEBCwUAA4IBAQBvGtz0xYQOX1SqTdutLLKSJdlUt3jin3NoEvvDKAHhmpnc DDMfamqM4wjXb1JlTQKSHAdgLB/KHMgJPlb4pn9pHVCsZ9cEwz0Qz0oGPyr/rmYC IZRfmImqKdDLDhVWyK8GLv6cYwQEkuRMzytXX8DMcJcWRXuJj3cuyVGQ7BKxSnl7 0U9pbUb8mNwcvJnZfsfL4AIQR2//NoTVI+XKXg9INoJXa4WaWXAYR4QlV1+Ow52P uGnBaCsCx+JbD+2hhbbGJNzPqG1ZaZUEvnQiqOTcVseeGg6uLZ4KAGaJ52ZVWcmT Lmt+TMkML8Ajm11mJnqJIclMXs61rsHVPHbjVl5q -----END CERTIFICATE REQUEST-----",
"crypto.frontsideKey": "-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEArZwnuu2oY+wWgU0uM5DTyScY7jb274R0gQ+Je9ye+6aEihKY 6q5Q7PIg6o8JjflayjYSNL3t0fdBr5fxCjwvoV+ZYMGfgLpFZU/HGHVrY/RMzV5L M8/9tVTTKCGB2A+RTqNh8DQ6acE3co4eXf2Bzzpwjy1dTGy2eUALO/6Z7VEqa8x/ L4gTcLSoG+8+OE2MhTi/H04n8NrEyHayEnEeW3vXyZlMLL98CoTltznX0C3HLto8 P0sVZDr+YZucvMfyXgyqtlgWRWRnHyHe5i3d7I3RyjgWJwG4a2Cz3uxVylnP20Lb IUSLbkiqX4B0a5or6Ew1TakXkZ01oBGXIuN6YQIDAQABAoIBAEI3znuhDFpYgVj+ PEIU2oLd88dglZ1T8zAK4hCpXMZ1hBY587OHm3xU+jMdLbLGSlfYeec+DkjIu3gj Rx/1RuGRWioqkBEEe1WiMTlmB/kPBIBMl/iCO63/Va734NOtVGofLUr2UNVniiOa i4CkIfANxUMHNY/h41OqFt7iRInci3ILaHBwvLQLUc0ZHZcP1jHH/6zLxsx7ueap XbOFOrRgVt620HIDBtCntJBO24KN3TveKuLSrZPGU3G/dilOEA8kTdl9ftD4Qgbe Y4sZ0sz72WjHNSVOrdTNfyLKPOmbTs+qGW7SZWOWkDmvmLO5fu6fPWnjZqTikaUz ZWfuhJUCgYEA3x1+573AblgZGshKWFa33dYHvCOVjaqUfbNyvqWEA64vl/VBhOGU 8WUFAVlqX5tN1NxUF9KLF5Ed2iIRb8d1VUb4gTCs8BVX1rJN2VFzYIBwr66G/9bO KHAH2ABq7PgRWxEBvsvgbD6gwPAgWtx+KiSGaX1V3qvmASoz1Vj4wMcCgYEAxzK+ 1YngK9Jc4JgJMYqkfRHKwjBq99CzKJHKtXzaHVqcFmH2OqmwGWb4t0DyQsi5PKVM u4OFS3/vgSKpEwem94dB6OwuAioeX6pSkYW4qGLhOm9V9iPrjg/Q4v5+ym6iNMB+ 0CZdeR1TGI1qLFkv8ziSdN1K2Ycv2fYGSRpNE5cCgYEAgTG2M4C39e1DlDOYgTCt xWHTFslQJzk4RNVtQyHaoLrzSj21E7oAIgvJ6y8YnoXyeqiedTDwY9QfAhmqGRzZ P2kaKszBxz/EnkifNZCpi560Ibag63I57EZ69EPBprg6bI4bgZzStjtJoI8rXRHC aKq/vkPaPlcxl0kVvJuJZy8CgYEApqw7KQl4XLJjrDkKWD2dbFjawqkol7o0bhmu 9zREfJM4TzIgiO06v8Z9DTh2fJLfC3N0ROHDQm0FxZNuzNF2T18JMw+LX5xGVd15 wPGWlK5HrlFCJ/XePrvVGFnBVThE2MbIVPoE9DYpNT3+PKVTjbskMEyJOIH48/L7 R2eOXnkCgYBRCjh9ns9PSneKWGfz+ymlB0b4kCZBU69Q3ladgN50oxG6QmiccObT EXEeUl+XqhlhyR7MeNSz7IUugHSVKqpa2fGFTQ3Uk7k6QslSXHcJFl3HBjK/Ejcc H8zB9FPVe1gOqeK2HBnThC7zWOseGrBMWhyeH2cNdGXnw+dexWUTig== -----END RSA PRIVATE KEY-----",
"datapowerEnv.workerThreads": "4",
"image.pullPolicy": "IfNotPresent",
"image.repository": "ibmcom/datapower",
"image.tag": "7.6.0",
"patternName": "webApplicationProxy",
"replicaCount": "1",
"resources.limits.cpu": "4",
"resources.limits.memory": "8Gi",
"resources.requests.cpu": "2",
"resources.requests.memory": "4Gi",
"service.name": "datapower",
"service.type": "NodePort",
"webApplicationProxy.backendURL": "https://www.ibm.com",
"webApplicationProxy.containerPort": "8443"
}
}
and it failed (and no log info is available)
Just to complete info I generate the cert/key inside linux with the following command
generate key
openssl genrsa -out /tmp/hostname.key 2048
genrate cert
openssl req -new -key /tmp/hostname.key -out /tmp/hostname-2017.req
what is wrong ? where info/log is available to understand the error ?
The only way I can get the ICP GUI to accept my keys and certs is to strip out the header, footer, and line feeds. Only one continuous, encrypted string remains.
You should base64 encode the key and cert. They'll be used as a k8s secret, and those are required to be base64 encoded.
First, let's understand what these values are doing.
Each of the keys crypto.frontsideCert and crypto.frontsideKey map to values used in a Kubernetes secret. You can actually see how these values are substituted in the chart:
https://github.com/IBM/charts/blob/master/stable/ibm-datapower-dev/templates/secrets.yaml#L7-L8
And to provide a secret to Kubernetes, the value must be base-64 encoded. While the secret isn't really encrypted, it will be obscured from casual observation.
You can base64 encode these strings using base64 on your favorite linux distro:
cat /tmp/hostname.key | base64
# Outputs a large block of text, which typically ends in "==" cat
cat /tmp/hostname-2017.req | base64
# Outputs a large block of text, which typically ends in "=="
If you're ever concerned that the value in a secret isn't what you expect, you can always verify it:
echo "This is an obscured secret." | base64
VGhpcyBpcyBhbiBvYnNjdXJlZCBzZWNyZXQuCg==
echo VGhpcyBpcyBhbiBvYnNjdXJlZCBzZWNyZXQuCg== | base64 --decode
This is an obscured secret.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
How can I decrypt a message signed with a private key in golang?
$ openssl genrsa -out ./server/server.key
Generating RSA private key, 2048 bit long modulus
..................+++
.............................................+++
$ openssl rsa -in ./server/server.key -pubout -out ./client/client.pub
writing RSA key
$ echo "secret" | openssl rsautl -inkey ./server/server.key -sign > ./secret
# decrypt with public key
$ openssl rsautl -inkey ./client/client.pub -pubin -in ./secret
secret
I fully understood my question, it was about RSA_public_decrypt method of openssl: https://www.openssl.org/docs/man1.1.0/crypto/RSA_public_decrypt.html
I did not found any pure-golang realization. Realization with cgo: https://github.com/dgkang/rsa/blob/master/rsa/rsa.go
UPD, work for me:
func RSA_public_decrypt(pubKey *rsa.PublicKey, data []byte) []byte {
c := new(big.Int)
m := new(big.Int)
m.SetBytes(data)
e := big.NewInt(int64(pubKey.E))
c.Exp(m, e, pubKey.N)
out := c.Bytes()
skip := 0
for i := 2; i < len(out); i++ {
if i+1 >= len(out) {
break
}
if out[i] == 0xff && out[i+1] == 0 {
skip = i + 2
break
}
}
return out[skip:]
}
I think there is a bit of a misunderstanding here. openssl rsautl -sign does not encrypt the data. It produces a signature. The contents in your secret file is not "secret", encrypted. Rather, it is a signature of the text "secret" that is signed with the private key.
Using the public key, you can -verify the signature, but this isn't really what you are trying to do. It sounds like you want encrypt/decrypt, not sign/verify.
Use the -encrypt and -decrypt options of rsautl. Encryption happens with the public key, and decryption happens with the private key.
Keep in mind there are limits to the amount of data you can encrypt with RSA. Typically, you would protect a symmetric key with RSA, and use the symmetric key to do bulk encryption and decryption.
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.
I'm using the following command to encrypt my private key file using OpenSSL:
$ openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der -v1 PBE-SHA1-3DES
The documentation states that the option -v1 PBE-SHA1-3DES will encrypt using triple DES, but doesn't mention which keying option it is using. Can I assume that it uses 168 bit triple DES?
The answer seems to be yes, when I read the file from Java(see also my other question), I can get the algorithm viz.:
1.2.840.113549.1.12.1.3 from algParams.getAlgorithm()
Googling this yields: pbeWithSHAAnd3-KeyTripleDES-CBC
See also: http://www.oid-info.com/get/1.2.840.113549.1.12.1.3
This is a 3key triple DES, which entails 168 bits.
public static byte[] decryptPrivateKey(byte[] key) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
PBEKeySpec passKeySpec = new PBEKeySpec("p".toCharArray());
EncryptedPrivateKeyInfo encryptedKey = new EncryptedPrivateKeyInfo(key);
System.out.println(encryptedKey.getAlgName());
System.out.println("key length: " + key.length);
AlgorithmParameters algParams = encryptedKey.getAlgParameters();
System.out.println(algParams.getAlgorithm());