[CryptoAPI] AES256 methods will work on this scenario?

[CryptoAPI] AES256 methods will work on this scenario?

  
Forge Component
(13)
Published on 17 Oct (4 days ago) by Ricardo Silva
13 votes
Published on 17 Oct (4 days ago) by Ricardo Silva

Hi all,


I have this requirement below but I can't get the correct results (encrypted /decrypted values) with none of the methods provided by this extension, maybe I'm doing something wrong...:( can you confirm(from your experience) if is possible or not possible use one of the methods provided by this extension to achieve what's asked below.

The goal is to send some data encrypted so they can decrypt and vice-versa.

PS: I send them the C# code of all methods from this extension, I assume they used on of these but I will confirm.

Thank you in advance  for your help.

Cheers

Goncalo


"Password encryption

We had a look at the encryptions you suggested and here is what I have from the dev team:

This seems to work OK:

#!/usr/bin/perl

 use strict;
 use warnings;
 use Crypt::CBC;

 my $key = 'little brown mouse';
 my $data = '{ firstfield => "abc", secondfield = > "def" } ';
 my $cipher = Crypt::CBC->new(
 -key => $key,
 -keylength => '256',
 -cipher => "Crypt::OpenSSL::AES"
 );

 my $encrypted = $cipher->encrypt_hex($data);
 my $decrypted = $cipher->decrypt_hex($encrypted);

 print $encrypted, "\n";
 print $decrypted, "\n";

the output is:

$ perl aes_cbc.pl
 53616c7465645f5ffc74861d1981a9427de14e170397f4aa266ce162ef0f32d4cc9de154c3cdc8ddff20931f737bfae1919d160d5ec05b398ac704f72db2d5f4
 { firstfield => "abc", secondfield = > "def" }

So if you can turn the hex above (53616…) into { firstfield => "abc", secondfield = > "def" }

using “little brown mouse” as the key to AES, then we’re in business.

Or even turn { firstfield => "abc", secondfield = > "def" } into the same hex (53616…) using the key “little brown mouse" "

Hello,


Does the backend have to be in Perl ? I have created a Python library with an implementation of this extension methods:

https://github.com/ardoric/ardoCrypto/blob/master/ardoCrypto.py

Do you need to integrate specifically with that code?

Hi Ricardo,

thank you for quick feedback on this.

Our end game here it's no find a solution where I can send them some encrypted data from OS and they can decrypt on their side and they can send encrypted data and I can decrypt using the same key/password of course. 

Like I said I tried to encrypt and decrypt the test values they sent with the methods available on this extension but I was not able to get the correct results (decrypt or encrypt and get the same results), do you think one of the parts needs to install customized methods so we can achieve this?

I will ask them if they can use another language instead of pearl.


Thank you!


Cheers

Well, if what you are trying to do is to communicate an encrypted value between OutSystems and your application and you have no legacy to think of, I would recommend you indeed use CryptoAPI.

In the Documentation topic you have a description of the encryption scheme that CryptoAPI uses, and it should be easy enough to implement in any language.

I wholeheartedly recommend AGAINST using the scheme your development team is trying to use as it has several flaws. A quick search on google in order to understand what it is doing yielded a couple of results where its use is discouraged (e.g. here and here ).

Hi Ricardo,


thank you for your help and advises.


We tried now to use a different approach and use methods from your extension.

Below is the feedback I received from the other dev team but I tried to encrypt and decrypt using the public/private key they shared with me ( I removed from the post but I can send you by PM if you needed to test) but I getting always the error it's attached. Am I doing something wrong here or the encryption they are using still not compatible with the ones from your extension? They said they used the same methods I send the in C# but in perl.

Thank you for your help and sorry for the time you're spending on this.

Cheers

"We had another go by changing direction and using the API that was supplied originally – it does support RSA, which might be a better avenue of attack. Here is what we have done and can try out:

Using the following public key:

-----BEGIN CERTIFICATE-----

Just removed for security reasons

-----END CERTIFICATE——

and the same text as before:

"{ firstfield => "abc", secondfield = > "def” }”

the API call is MssRSAEncrypt.

To decrypt messages they need the Private key:

-----BEGIN PRIVATE KEY-----

Just removed for security reasons

-----END PRIVATE KEY——

and use the MssRSADecrypt API call.

We’ve encrypted the text using the public key, which should be able to be decrypted with MssRSADecrypt (this is Base64 encoded):

U4zxS4sQ+My6eXFi8wBmHLUOfQxuq3SGsTSVfScVotd7MhsH1OoGc4oC1SHkuvyjkbj9vWtehLQL

2WjpWDhdu14iFb5FA+4mEMYj98W7c+0X/CXpehhJsQNufuQCiHq1OAQlv4poD0jXRyhDVUfAs+49

nR4RndF2u7A2SIlGn5Y3ldiZemzjyl3OQOOtvknwpHiutUznsrs/UT4DEP1GC5igwBe2PHxi1AUv

dkSOvb7andlQDJUlaqcLtfs0Mdq2oGBH8PELKlZyA9gmkU4StNI5J8pbflyoP14+LcTYfJdM46rl

gFr+kNtF7C0VvhLZwkHAQULgw6KyK03CpsjD1Q==

using the following code:

#!/usr/bin/perl

use Crypt::OpenSSL::RSA;

use Crypt::OpenSSL::X509;

use MIME::Base64;

use strict;

my $public_key = '/home/mvine/perlsaml/certs/sisenc.crt';

my $string = '{ firstfield => "abc", secondfield = > "def" }';

print encryptPublic($public_key,$string);

exit;

sub encryptPublic {

my ($public_key,$string) = @_;

my $key_string;

open(PUB,$public_key) || die "$public_key: $!";

read(PUB,$key_string,-s PUB); # Suck in the whole file

close(PUB);

my $cert = Crypt::OpenSSL::X509->new_from_string($key_string);

my $public =

Crypt::OpenSSL::RSA->new_public_key($cert->pubkey);

return encode_base64($public->encrypt($string));

}

Solution

Well, the short answer is that you're getting that error because the private key you're providing is not in the expected format. If you're providing a key in base64 encoded pkcs1, which you seem you are, that is not the format CryptoAPI takes its key.


A CryptoAPI private key looks something like this, which is the format .NET exports its RSA keys:

<RSAKeyValue><Modulus>zIlbxfrKSoQ337GnTWTp7SQ139ZtGbB/CerRR6G7EeFexDov9jTsQazoBzU5Wsi0eEDKhIE9qJIkUgTHSobdyc3Jiw/vBobV5sQLfwCLDQVxxEX9I0R1pdfv2PhO/i/bzDJvpTYRdlX9PQSpNhOp51Sj3qJL77UdEytI4AHZqoYjnpU/tMTsSvyJTfNxc8OOX/AaOPnW90HjLTn9OyijMqPrFw5iJ/xsJmFTR0EGzzJuSb7f5MlgZ1LAODFKkOQmCDme4oISu8mUGriR5thsXTZf9Vr1cIq4zrF1yYR3we1dQAgSo8pQg9M/YS5KkJvDCDZsObcCF3tVUdwYggzpew==</Modulus>

<Exponent>AQAB</Exponent><P>8369VLd4zV+3WhMDmSXZCZ53VO2XtizQnx8znX9uMIgYqaF/M1pVVHfnF6zE1WWdl2dV/mAyRq+ixPkKIjZkk3TsnK2I4KkzkdWAem2yOBvTUfqikry238a0wrf3Dj5RVeibmD1+fqQE8IBNaEjgMMaekBKCO7LQr01X4P7EtO8=</P><Q>1wptJUshwI183gsxQVzK/VZyY/Ju/eq+mVLJJadYUKRHiK3//t5wNb42DRiJ+rWdkTRyARNJQkHHmjNRXR5XThMQOGCjPvn0V4KjY+O+p6iXFhu8gcTr9Q6FHKm6itue6IXk7teG98Z44SrQmvRA0zJk2ruadR7CtmbeG1ErzDU=</Q><DP>vItoGcBT91tlg4bzo1PuQoeFSasMbdE33e7wLcWt0kCgMEHQWDhbmKObuvZaGA+uPr2Slf1xENERjcp1cVaC/LduPEgXlDcQqp0S9joY5V+Oe41C87LTPGYGNDz1Pf89RfNvACyl1XQ2KvB+gADmMH6r602ZsJZfB08xfBRqxts=</DP><DQ>JZ58U57eK7pU0t9wYXfjRwh9gICj7CXJ7DawW7b32zuyC/Ysp6CwTqaU/BuD3+kvxHxBSXDfSwkI6y/5Fuo86bqqBsLZLCY8GacQAGSSMPBsZgC6LJWPldJRdR84NByRoynxT9tCkEwXT4TW85SxVoElZaKWNdEIzTIXvv2nRNU=</DQ><InverseQ>n4yUQvM2Bzyvx10sl/dhiluUfEFTYuce1vZpNNFyvg7raxn0xgVmYiKKx+zaa6Ix+F9fbL5krqVWtWrITAL5LsAEG/rhZmdwgqwkTLBEIMrSdlAUzsYaWDPeBRQEES28KoyOHAeHItiDBzc8XzcCT0SH9RF4JOIPNxdLdngulII=</InverseQ><D>CtROkYQ03k6M0ZR+43g8Pt8j1eOgNPPlOtNKqSYoTCSO5Dw7QNs0rRXocEVCcaRekpIsbTXIjw3M/xi1ePEvrTK7mosv7SKjdz6zzlG38WsNE60rxdVaMBTN5EKu/M9WesPEdhtcP+2cMfUp6yz0WhHfRHdHjPwD+5Lw0bqkJl6Wg62t2CaQU4Ft88vkAwU+O423BsLsx3cWvUFbIcW/8zpcfkuXzp/gK4/4l5tWIR/ILSzjXXkxHYZXT3POeTNqmRDFR0kVTQPcqviJ+TDMpWRoDc+i06z5PMKdQ7oxXSfONp4C5uUhfqWvk6wRLE7VIdfIZsTHZWuhaLGCtnaBlQ==</D></RSAKeyValue>



You can probably build this from your private key in perl using the "get_key_parameters" method.

.NET does not seem to provide good support built-in support for handling pkcs1 keys, so ... yeah ...

Solution

Hi again Ricardo,

I passed to the third party dev team the inputs you pass me on the previous post and this was their answer/solution:

"Hi,

After a little research, it would appear that the XML format below is .NET specific and is unusable anywhere else.

 We did some further research and think that the attached pfx file can be imported into a Microsoft key store and exported in a suitable format from there."

Do you think from the .pfx file they sent me I can get the correct public/private RSA keys to use on CryptoAPI methods? If yes, how can get these values?

Sorry for all the questions but this is all new for me.

Thank you again for your help.


Cheers

Not exactly unusable*, but I do get their point.

Yes, if you get a pfx file, it seems that you should be able to obtain the xml representation of the key. See this stack overflow post for an example.

In any case, you seem to be wanting to encrypt JSON data. With this method and a 2048 bit key, you'll only be able to encrypt about 200 bytes of data. Do you think this will be enough for all future use of this ... integration?

Can't you simply use the python code I have provided? Can't your dev team build the symmetric encryption schema in perl?

*after some googling, I was able to use it in Java which doesn't support this format natively

Hi Ricardo,

I was able to use a workaround and get the "compatible" RSA xml structure from the private key they provide me using this tool: https://superdry.apphb.com/tools/online-rsa-key-converter

After I get the RSA XML structure I was able to use it in the CryptoAPI "RSADecrypt" method. To get the RSA public key I used your method "GetRSAPublicKey" passing the RSA private key and I was able to get a proper RSA public key that I use on the "RSAEncrypt" method. Now I'm able to decrypt/encrypt the data that the third party dev team sent to me. I'm not sure if is the best way to do it...but at the moment seems to work.

Now you raised a good point, the size of the data to encrypt/decrypt...I think we are going to drop the all package JSON encryption and only encrypt the value of the inputs we are passing on REST API. On that case, because are small data I think will work ok, but you're are right in future this encryption method maybe it's not the best one to use.

Ricardo just one idea, will not be possible to implement the same logic that website is using to get the the XML RSA keys from a .pem or .pfx directly on the CryptoAPI extension without using a third party logic? That would be awesome :)


Thank you again for amazing help on this!


Cheers,

Goncalo  


Yes, that would be awesome, but it's also dependent on adding an additional 3rd party library which I would prefer to avoid, if possible.

As for the adequacy of the encryption methods used, it will depend a bit on how much the systems communicate.

Note that asymmetric encryption is much more CPU intensive than symmetric encryption, so it may also become a liability if the systems are always communicating.

This can also be viewed as a potential venue for a DoS attack, if an attacker can get your system to attempt decryption of large quantities of data / requests without proper clearance.