Java and C++ Cryptography interoperability - c++

I have a message coming from an external company which has been encrypted with our public key using Java.
Specifically the java code performing the encryption is -
//get instance of cipher using BouncyCastle cryptography provider
Cipher cipher = Cipher.getInstance( "RSA/ECB/PKCS1Padding", "BC");
//initialize the cipher with the public key pulled from the X509 certificate
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
I need to be able to decrypt this message using our private key using C/C++ on Solaris.
I have tried using the Crypto++ library and can successfully encode decode messages just using Crypto++, but am unable to work out how to decode the message encrypted from the java side.
Specifically I tried using a RSAES_PKCS1v15_Decryptor but this does not seem to work.
Does anyone have any suggestions as to how I can perform the decryption such as
The required Crypto++ code (ideal)
Alternatives to RSA/ECB/PKCS1Padding to use from the Java side
Alternative open source C libraries I could try
Anything else...

I managed to get this working by changing the java code to use
Cipher cipher = Cipher.getInstance( "RSA/NONE/PKCS1Padding", "BC");
This then matches up with RSAES_PKCS1v15_Decryptor on the Crypto++ side.

Related

AES > Base64 Encryption/Decryption and 256bit mode

I need to create a internal AES/Base64 encrypt system for my application.
I mean , I don't want to have any side dll for my exe like openssl library.
I found this threads :
Problems with CryptoPP C++ AES-256+Base64
Crypto++ encrypt and decrypt in two different c++ programs
But they wasn't what I need , I searched and I found nothing.
What I need exactly is like this site : https://aesencryption.net/
First an AES encryption with a key at 256bit mode
Next convert it to Base64 ( a Result of encryption in base64 in aesencryption.net )
And a decrypt system to get the first string from encrypted result.
In this thread the key has to be 32 lenght but in the aesencryption.net it can be everything .
Can you please guide me how can I create a system like aesencryption.net site ?

wc_RsaSSL_Verify returns BAD_FUNC_ARG, and I can't tell why

I am trying to RSA public key decrypt a signed file using wolfcrypt - yes, I may or may not be abusing the "sign/verify" power of RSA to encrypt a separate AES key using the private key and decrypt using the public key.
Unfortunately, I am stuck at wc_RsaSSL_Verify() - for the life of me I can't figure out why it is returning BAD_FUNC_ARG - I figured an error like that should be immediately visible to somebody else so I'm deciding to call upon the collective powers of StackOverflow.
As far as I can tell, I'm giving the function what it's asking for - an input buffer, an output buffer, the size of each, and a pointer to the RsaKey struct. Here is a code snippet from the function in question:
bool VerifyWorker::GetAESKey()
{
bool result = true;
uint8_t en_aes_file_buff[VerifyWorkerLocal::RSA_KEY_SIZE];
uint8_t de_aes_file_buff[VerifyWorkerLocal::RSA_KEY_SIZE];
uint8_t* aes_iv_ptr = NULL;
// keyfile filestream
std::fstream aes_file;
// rsa_key must be initialized
if(rsa_key == NULL)
{
result = false;
}
// Open the key file and read it into a local buffer, then decrypt it and use it to initialize the
// aes struct
if(result)
{
aes_file.open(this->aes_key_file, std::ios_base::in | std::ios_base::binary);
if(aes_file.fail())
{
// Unable to open file - perror?
perror("GetAESKey");
result = false;
}
else
{
aes_file.read(reinterpret_cast<char*>(en_aes_file_buff), VerifyWorkerLocal::RSA_KEY_SIZE + 1);
if(!aes_file.eof())
{
// we didn't have enough space to read the whole signature!
std::cerr << "aes_file read failed! " << aes_file.rdstate() << std::endl;
result = false;
}
}
}
// "Unsign" the aes key file with RSA verify, and load the aes struct with the result
if(result)
{
int wc_ret = 0;
wc_ret = wc_RsaSSL_Verify(const_cast<const byte*>(en_aes_file_buff),
VerifyWorkerLocal::RSA_KEY_SIZE, reinterpret_cast<byte*>(&de_aes_file_buff),
VerifyWorkerLocal::RSA_KEY_SIZE, rsa_key);
The rsa_key is a private member initialized (successfully, using wc_PublicKeyDecode()) in a separate function with a public key DER file. I generated both the public and private key using OpenSSL - which should properly pad my AES key and iv file using PKCS#1 v1.5 b default.
I should also mention that I am using wolfssl version 3.9.8. Thanks!
The issue, I found, was that the file that I had signed with my RSA key was not signed correctly. When I signed the file using OpenSSL, my cli invocation was
openssl rsautl -in keyfile -out keyfile -inkey private.pem -sign
Apparently, openssl does not like you to specify the same file for -in and -out. When I changed it to something like
openssl rsautl -in keyfile -out keyfile_signed -inkey private.pem -sign
I was actually able to verify the file using wc_RsaSSL_Verify.
So, like most stupid late-night, last hour software problems, I was looking in the wrong place entirely. I was a bit thrown off by the BAD_FUNC_ARG being returned and thought that it had to do explicitly with the format of the function arguments, not necessarily their content. Hopefully this answer is useful for somebody else, too.
It sounds like you are trying to use RSA_Sign to perform an "Encrypt" of an AES key. Then I assume you are sending to a remote partner or computer who will then run an RSA_Verify operation to decrypt the AES key do I understand the scenario correctly?
If so I apologize it did not show up if you searched on how to do this initially but we actually have an example of doing exactly that here:
https://github.com/wolfSSL/wolfssl-examples/tree/master/signature/encryption-through-signing
That example includes two separate applications. The first app, "rsa-private-encrypt-app.c", will sign (encrypt) the "fake Aes Key" and output the result to a file. The second app, "rsa-public-decrypt-app.c", then opens the file that was output and does a verify (decrypt) on the data contained in the file to recover the original "fake Aes Key".
I may or may not be abusing the "sign/verify" power of RSA to encrypt a separate AES key using the private key and decrypt using the public key.
No not at all, that is a valid use of RSA sign/verify ASSUMING you are working with fixed-length inputs such as an AES key.
That's why we created the example! We actually had a user ask a very similar question on our forums awhile back which led to us making the example.
One thing to make note of though on the issues you encountered with openssl and wolfssl is actually talked about in the README:
https://github.com/wolfSSL/wolfssl-examples/blob/master/signature/encryption-through-signing/README.md
... Keep in mind this is not a TRUE RSA ENCRYPT and will likely not inter-op with other libraries that offer a RSA_PRIVATE_ENCRYPT type API.
This is a true SIGN operation.
If you have any other questions feel free to post them here (and add the wolfssl tag of course) or you can also send us an email anytime at support#wolfssl.com
Disclaimer: I work for wolfSSL Inc.

How to load RSA key pair without Openssl or other Library

CCFor a project I was searching for a simple RSA implementation to exchange a small secret via an unsecured but existing communication protocol. To keep it small and easy to portable to different platforms I did not want to link against OpenSSL or Crypto++. I found that as a part of the axTLS project which has a suitable license and an easy to extract RSA algorithm. The rsa function for encryption needs two components (as it usses the public key). The pup_exp is 65537 and modulus is the public part of the key and priv_exp the private one.
void RSA_priv_key_new(RSA_CTX **ctx,
const uint8_t *modulus, int mod_len,
const uint8_t *pub_exp, int pub_len,
const uint8_t *priv_exp, int priv_len
)
For easy use for the user, I want to load a certificate like X.509 or PEM generated by a library like OpenSSL, but in C or C++ code without including the whole OpenSSL stuff. But at the moment I even did not find an understandable documentation of the common key file formats.
There are two types of RSA public key format widely used and they are PKCS#1 and X.509(SubjectPublicKeyInfo).
I have used libtomcrypt(http://libtom.org/?page=features). It supports both the RSA key formats and very much portable. The license is non restrictive.

cryptoapi and openssl

I'm trying to encrypt and sign a file with cryptoapi with some X.509 certificates. I want to verify and decrypt this file with openssl.
On windows I think I need to use the CryptSignAndEncryptMessage function to encrypt and sign data. I used this example from MSDN to create a signed and encrypted message.
How can I decrypt/verify this file using openssl? I removed the first 4 bytes from the message since it contained the length of the message (from the windows blob).
When I call openssl -asn1parse I get some output that indicates it to be parsable by openssl.
When trying to verify the signature with openssl I recieve an error:
openssl rsautl -verify -inkey AlonsoCert.pem -keyform pem -certin -in sandvout-without-4byte.txt
RSA operation error
3073579208:error:0406706C:rsa routines:RSA_EAY_PUBLIC_DECRYPT:data greater than mod len:rsa_eay.c:680:
CryptSignAndEncrypt message seems to use RC4 cipher with empty ASN.1 parameters field and, looking at OpenSSL sources, openssl chokes on try to generate IV (which is not needed for RC4).
Try to use other cipher (AES for example) in CryptAndSignMessage.
Anyway, RC4 is very old, insecure, and obsolete.
Your ASN.1 dump information shows you've created a PKCS#7 CMS output from your CryptoAPI code. As a result you cannot use the basic OpenSSL decryption and verification methods.
Instead, use the cms mode:
openssl cms -decrypt -inform DER -in sandvout-without-4byte.txt
-out decrypted.bin -recip testkey.pfx
(Note: I've not used this mode before, so I think the syntax I've suggested is correct. Either way, this should hopefully be the step in the right direction that solves this.)
Try using openssl smime to verify and/or decrypt. The syntax is fairly straight-forward but you can find the information here: http://www.openssl.org/docs/apps/smime.html

RSA encrypt for C++ (BB10)

Resolved (look for my answer). I need help encrypting a password with RSA in C++. I'm working for Blackberry10 in C++ and I've been looking for a RSA tutorial or something that walk me through the encrypting process but sadly I haven't found anything consistant.
I've been told that the process consist basicaly in three steps:
1)Generate the RSA public key with the module and exponent.
2)Encrypt the text with the public key.
3)Encrypt the text again in base640.
If you are wondering why I need to follow this three steps is because I'm working in a banking app, and those are their requirements.
I've been searching all over and I haven't found even how to make the first step, generate the public key with the module and the exponent (I already have both).
Any help will be appreciated.
Thanks.
Is not that I'm building the whole app by myself. We are a team and I need to encrypt just the client password with RSA and send it to the next step of the process. I do have experiencie working with Blackberry and RSA but in Java, where the process is a little bit easier, e.g: In java the first step once you got the module and public exponent is create the RSA Public Key Object through a very simple syntaxis: RSAPublicKey publicKey = new RSAPublicKey(new RSACryptoSystem(2048),ebytes, mbytes);. In this part is where I'm little bit lost because I haven't found the proper BB10 documentation. I'm sorry if I created the illusion that I'm creating a whole encryption API by myself. BB10 has this security API based in hursa.h (https://developer.blackberry.com/native/beta/reference/com.qnx.doc.crypto/topic/about_rsa_raw.html) I'm trying to implement it, but I haven't been successful. #owlstead #dajames #bta
I highly recommend that you take advantage of an existing encryption library to handle all of this for you. OpenSSL is widely used, and the LibTom libraries include an encryption lib as well. Encryption is not an easy thing to implement from scratch, and you will save a considerable amount of time and frustration by using an existing implementation. OpenSSL in particular is a good choice, as it has passed FIPS certification tests multiple times. Since you're working on a banking app, you (and your customers) will most likely want to use an implementation that has been certified.
Even if you insist on implementing your own encryption libraries from scratch, I encourage you to check out the aforementioned libraries as examples.
It seems to me that you know even less than you think you do about how this cryptography works.
One doesn't usually use RSA encryption to encrypt data. It can be done for something short like a PIN or password, but what is usually done is to generate a symmetric key and to encrypt the data with the symmetric key and then use RSA to encrypt the symmetric key.
If you are sending a password to a bank then what you are probably supposed to be doing is to use the RSA key supplied by the bank in their own key certificate. Only the bank has the private key, so only they can decrypt the password. If that's right then you don't need to generate an RSA key, but you do need to verify that the certificate is trusted.
I don't program Blackberries, so I don't know what cryptography APIs they support, but I would expect everything you need to be built-in. This is all pretty standard stuff.
I recommend that you start by reading up on public key cryptography (e.g. on Wikipedia here and here) before starting to design your solution.
Resolved. After doing some research and getting to know better with BB10 coding and RSA, I finally came out with the solution to successfuly encrypt a plain text with RSA and Base64 in C/C++ for BB10 or any other platform. Please take in consideration that I have the modulus and the public exponent of the rsa object from the services that I'm working with.
The code:
QByteArray answer;
RSA* rsa = RSA_new();
BIGNUM *modulus = BN_new();
BIGNUM *exponent = BN_new();
const char *modulusString = rsaObj->getM(); //My Modulus
const char *exponentString = rsaObj->getE(); //My exponent
BN_hex2bn(&modulus, modulusString);
BN_hex2bn(&exponent, exponentString);
rsa->n = BN_new();
BN_copy(rsa->n, modulus);
rsa->e = BN_new();
BN_copy(rsa->e, exponent);
int maxSize = RSA_size(rsa);
qDebug() << "maxSize:" << maxSize;
const char *inn = "1234";
unsigned char *encrypted = (unsigned char*) malloc(maxSize);
int bufferSize = RSA_public_encrypt(strlen(inn), (unsigned char *) inn,
encrypted, rsa, RSA_PKCS1_PADDING);
if (bufferSize == -1) {
RSA_free(rsa);
qDebug() << "Error";
}
QByteArray enc = QByteArray::fromRawData((const char*) encrypted, 256);
answer = enc.toBase64();
return answer;
Thanks and I expect this helps to the new BB10 developers