Decrypt data using private key in SSL context in openssl (ssl_st) - encryption

Is it possible to get the private key of a TLS session from the SSL* context variable? I have a string encrypted with the public key and I would like to decrypt it using the corresponding private key from an SSL* context.
I have tried this but is doesn't work:
EVP_PKEY_CTX *ctx;
ctx = EVP_PKEY_CTX_new(pkey, NULL);
EVP_PKEY_decrypt(ctx, *out, &outlen, in, inlen)
where:
pkey is s->cert->key->privatekey (s is an already existing SSL* variable in the TLS session)
in/inlen is the encrypted string,
out/outlen is the expected output.
Any suggestion is welcome. Thanks.

Sorry, that code is actually working, it was just a problem with the padding.
I was calling:
EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING);
As soon as I removed that line the decryption worked. I don't actully know why, anybody can explain how padding works? I mean, should I know what kind of padding has been used or I just can ignore it (i.e. remove the line)

Related

Classic ASP AESDecrypt for SagePay 3.00

I am using classic asp to upgrade to SagePay 3.00.
When receiving the crypt response back from SagePay, I am successfully decrypting that and displaying the long string on the screen.
What I need to do is separate the pairs so I can use that information, such as VendorTxCode.
I have successfully used rijndael.asp and includes.asp to Encrypt, send the information to SagePay and decrypt.
How can I perform what I think is the final task by listing the values separately from the string?
I have encrypted and decrypted with these two functions :
public function EncryptAndEncode(strIn)
'** AES encryption, CBC blocking with PKCS5 padding then HEX encoding - DEFAULT **
EncryptAndEncode="#" & AESEncrypt(strIn,strEncryptionPassword)
end function
** Wrapper function do decode then decrypt based on header of the encrypted field **
public function DecodeAndDecrypt(strIn)
DecodeAndDecrypt=AESDecrypt(mid(strIn,2),strEncryptionPassword)
end function
Thanks.
Something like this should work:
dim decryptedString, values, value
decryptedString = "value1,value2,value3"
values = Split("decryptedString", ",")
for each value in values
Response.Write(value & "<br />")
next
Depending on the delimiter a regular expression might be required.
Thank you for your response and help.
This is what I have now :
transinfo = Request.QueryString("Crypt")
decryptthis = DecodeAndDecrypt(transinfo)
Which successfully receives the string, the decrypts it. I am still unsure how to take the individual values out with your code.
I specifically need to take the VendorTxCode & related value out of the string.
when I output decryptthis to the screen, I see it, but I need to take it out of the string so I can use it.

Key not valid for use in specified state error when using ProtectedData.Unprotect

I have a little problem in using a simple ProtectedData.Unprotect call, here's the code I'm sharing, maybe I'm missing something here.
public static byte[] SampleDecrypt(IEncrypted symmetricallyEncrypted, string base64DpapiLocalEncyrptedKey)
{
if (base64DpapiLocalEncryptedKey == null)
{
throw new ArgumentNullException("base64DpapiLocalEncryptedKey");
}
byte[] unprotectedKey =
ProtectedData.Unprotect(
base64DpapiLocalEncyrptedKey,
null,
DataProtectionScope.LocalMachine);
return unprotectedKey;
}
Where base64DpapiLocalEncyrptedKey is:
"ABCCENCMnd8CFdERjHoAVV/Pl+sMAAAA4q4wemrun5a67ohPku3cIAQCCCBAAAAKKKDZgAAqAAAABADDDCvGV5W6fCNcWbb9LPZp2U3AAAYYYSBBBCgDDDDEAAAANlpDcUbBvGqMyHXk8CPtUEoBBBBlB1TtMZRC05ASxGV1/c3U548eVSPUO4X307ZDjRYytjNC35Di92q9RQAAACN//xNkexvIrGULI9GG9MdyS9Lee=="
when I ran the above it gives me the "Key not valid for use in specified state"
Thank you so much in advance guys!
I've figured out the problem. DPAPI pairs the encrypted key with your machine (assuming it's encrypted using a machine scope) in my case, localmachine scope was used.
Thought it may help anyone out there having the same issues. Try the key onto different machines to see if one works and not on the other to verify that you have a wrong key.
I created a new key off of a different server and was able to use it.

Decrypting a string using erlang + RSA

I have two separated applications, one written in Java and other in Erlang.
Both applications send messages to each other in String format, and those messages are encrypted in the Java app and need to be decrypted in the Erlang app.
The problem is this:
I'm using RSA public/private keys to do the encryption/decryption.
If I encrypt the data and decrypt all inside the my Erlang code, everything is fine. But, I'm not able to decrypt the string coming from my java endpoint.
Here's a simple test I'm doing:
PrivKey = "-----BEGIN RSA PRIVATE KEY----- ...",
% Data is the string I receive from Java
Data = "s013aA/SGN2iGYEbEIXXKvJiipqisRVfVEDneL8npRgThTHxTnYZESzVfCF463phPZyo5aOozisU7pwDdGKXgY8aqYZC+a3uES5muTb2RrzJ17yYku+g4S44vgIwZ9EyustZafNVGEYfgbWOYaPP/q5k683uR+MRHVqp6UbqMok=",
[PrivEntry] = public_key:pem_decode(list_to_binary(PrivKey)),
Priv = public_key:pem_entry_decode(PrivEntry),
BinData = iolist_to_binary(Data),
public_key:decrypt_private(Data, Priv).
Executing this code generates an error like this:
** exception error: decrypt_failed
I think the problem is in the format of BinData, but I couldn't find any place saying how I encode a string to pass to decrypt_private function.
Does anyone knows how to do this? This seems simple, but is taking me a lot of time to figure out.
Thanks.
After digging a little bit more, I found the answer!
I needed to decode my string into a base64 binary.
PrivKey = "-----BEGIN RSA PRIVATE KEY----- ...",
% Data is the string I receive from Java
Data = "s013aA/SGN2iGYEbEIXXKvJiipqisRVfVEDneL8npRgThTHxTnYZESzVfCF463phPZyo5aOozisU7pwDdGKXgY8aqYZC+a3uES5muTb2RrzJ17yYku+g4S44vgIwZ9EyustZafNVGEYfgbWOYaPP/q5k683uR+MRHVqp6UbqMok=",
[PrivEntry] = public_key:pem_decode(list_to_binary(PrivKey)),
Priv = public_key:pem_entry_decode(PrivEntry),
BinData = base64:decode(Data), %<-- THIS IS THE MAGIC
public_key:decrypt_private(BinData, Priv).
Hope this helps other people.

Sample X509Certificate2 RawData to use for unit tests?

I'm working on some RSA encryption/decryption unit tests and all of my functions require some certificates. I'm using dependency injection for these certs so for my unit tests, I'd like to just get some sample dummy (but functional) certificate to test my encryption/decryption library. I'd like to do this by hardcoding the RawData of valid certificate in my unit tests' SetUp method.
Where can I find something like this to put into my unit tests' SetUp method? Or how can I create this and pull this "raw data"? I'm not sure exactly what this "RawData" is. If somebody has something posted online (which would obviously be insecure, which is fine for my unit testing purposes), that would be preferable (from a lazy perspective) but I'm fine generating a cert and pulling this data as well.
Use .Export() instead of .RawData
When the X509Certificate2 has a private key within you can call:
var certBytes = certificateWithPrivateKey.Export(X509ContentType.Pkcs12);
Which returns a byte[] similar to .RawData, but it keeps the private key.
To store this in a unit test, you could just have a const string as Base64 of that data. Which you would get from:
var certAsString = Convert.ToBase64String(certBytes);
You can restore the key from this byte[] by constructing a X509Certificate2 with it:
var certificateCopy = new X509Certificate2(certBytes);
// Or from the string:
var certificateCopy2 = new X509Certificate2(Convert.FromBase64String(certAsString));
I don't understand it but this is what's going on...
I have a helper method that I call:
var cert = X509CertificateHelper.LoadCertificate(StoreName.My, StoreLocation.LocalMachine, "thumbprintgoeshere");
When I call this, cert is successfully populated and even HasPrivateKey is true. However, if I then do the following:
var cert2 = new X509Certificate2(cert.RawData);
then the resulting cert2 certificate, which is also what appears to be a valid certificate, has HasPrivateKey set to false. It appears that the RawData property "strips" out the private key (and yes, it's exportable - I have no problems creating a .pfx w/private key and importing it on another system and reproducing this behavior).
Now that I've discovered all of this, my solution is no longer to hardcode the RawData but instead to actually load up a certificate out of the certificate store - exactly what I was trying to avoid doing. If somebody has a better idea, please lay it on me. But until then, I'm calling this a failure and this is my end result. :-(

A way to generate a signature or a hash of an image in ASP.NET for duplicate detection?

I run a rather large site where my members add thousands of images every day. Obviously there is a lot of duplication and i was just wondering if during an upload of an image i can somehow generate a signature or a hash of an image so i can store it. And every time someone uploads the picture i would simply run a check if this signature already exists and fire an error stating that this image already exists. Not sure if this kind of technology already exists for asp.net but i am aware of tineye.com which sort of does it already.
If you think you can help i would appreciate your input.
Kris
A keyword that might be of interest is perceptual hashing.
You use any derived HashAlgorithm to generate a hash from the byte array of the file. Usually MD5 is used, but you could subsitute this for any of those provided in the System.Security.Cryptography namespace. This works for any binary, not just images.
Lots of sites provide MD5 hashes when you download files to verify if you've downloaded the file properly. For instance, an ISO CD/DVD image may be missing bytes when you've received the whole thing. Once you've downloaded the file, you generate the hash for it and make sure it's the same as the site says it should be. If all compares, you've got an exact copy.
I would probably use something similar to this:
public static class Helpers
{
//If you're running .NET 2.0 or lower, remove the 'this' keyword from the
//method signature as 2.0 doesn't support extension methods.
static string GetHashString(this byte[] bytes, HashAlgorithm cryptoProvider)
{
byte[] hash = cryptoProvider.ComputeHash(bytes);
return Convert.ToBase64String(hash);
}
}
Requires:
using System.Security.Cryptography;
Call using:
byte[] bytes = File.ReadAllBytes("FilePath");
string filehash = bytes.GetHashString(new MD5CryptoServiceProvider());
or if you're running in .NET 2.0 or lower:
string filehash = Helpers.GetHashString(File.ReadAllBytes("FilePath"), new MD5CryptoServiceProvider());
If you were to decide to go with a different hashing method instead of MD5 for the miniscule probability of collisions:
string filehash = bytes.GetHashString(new SHA1CryptoServiceProvider());
This way your has method isn't crypto provider specific and if you were to decide you wanted to change which crypto provider you're using, you just inject a different one into the cryptoProvider parameter.
You can use any of the other hashing classes just by changing the service provider you pass in:
string md5Hash = bytes.GetHashString(new MD5CryptoServiceProvider());
string sha1Hash = bytes.GetHashString(new SHA1CryptoServiceProvider());
string sha256Hash = bytes.GetHashString(new SHA256CryptoServiceProvider());
string sha384Hash = bytes.GetHashString(new SHA384CryptoServiceProvider());
string sha512Hash = bytes.GetHashString(new SHA512CryptoServiceProvider());
Typically you'd just use MD5 or similar to create a hash. This isn't guaranteed to be unique though, so I'd recommend you use the hash as a starting point. Identify if the image matches any known hashes you stored, then individually load the ones that it does match and do a full byte comparison on the potential collisions to be sure.
Another, simpler technique though is to simply pick a smallish number of bits and read first part of the image... store that number of starting bits as if they were a hash. This still gives you a small number of potential collisions that you'd need to check, but has much less overhead.
Look in the System.Security.Cryptography namespace. You have your choice of several hashing algorithms/implementations. Here's an example using md5, but since you have a lot of these you might want something bigger like SHA1:
public byte[] HashImage(Stream imageData)
{
return new MD5CryptoServiceProvider().ComputeHash(imageData);
}
I don't know if it already exists or not, but I can't think of a reason you can't do this yourself. Something similar to this will get you a hash of the file.
var fileStream = Request.Files[0].InputStream;//the uploaded file
var hasher = System.Security.Cryptography.HMACMD5();
var theHash = hasher.ComputeHash(fileStream);
System.Security.Cryptography

Resources