C# Chilkat RSA Asymmetric Encryption Bytes - c#

I'm using C# Chilkat library. In this example; I can encrypt the file with public key and open it with private key. But in my scenario there is no physical file for encrypt, at runtime I have byte arrays. And I want to encrypt it with public key and save as a file. Then I want to decrypt it with private key. Is there anyway to do it? I can't find any sample code about this.

It is possible to do that. If you looked over the whole example closely, you will have seen this line:
string encryptedAesKey = rsa2.EncryptStringENC(randomKey,bUsePrivateKey);
Earlier in the program, I saw that randomKey is a string. So that is how you can encrypt strings in memory. The program does not show how to encrypt a byte array, but clicking on the Chillkat.Rsa hyperlink in the program, you will go to this page.
There, you will see the methods available to you. EncryptStringENC is there, the method to encrypt a string and return a string. Note that there are 3 other Encrypt methods there, 2 of which will accept a byte array, one returning an encrypted string and the other an encrypted byte array. You should choose the one among these that meets your requirements.
As for saving the encrypted byte array to file, there are a lot of tutorials on saving to file, so for sake of brevity, I will not go into that here.

Related

What does CreateSignature(HashAlgorithm) achieve?

I am working with some old code and I don't understand what has been done when creating a signed hash. The authors used this implementation:
AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm)
All the examples I can find, and all the Microsoft documentation, use the other implementation:
AsymmetricSignatureFormatter.CreateSignature(byte[]HashedDataValue)
I understand that the second approach is signing a hash of some user data. At the receiver, we can re-hash the received plain text and compare it with this sent signed version to confirm it hasn't been changed.
But what is the first approach trying to do? No signed data seems to be sent, only a signed version of 'the agorithm', but what actually gets signed? Does it sign the Hash.hash byte array? But if so, there is no plain text byte array at the receiver to re-hash and check the sent hash against.
I suspect I have some fundamental misunderstanding of the purpose of this implementation.
It turns out that to use this form:
AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm)
you need to have done some pre-work with the HashAlgorithm object. The HashAlgorithm object internally stores the hash of the last thing it 'hashed'.
Hence, if alg is the HashAlgorithm and userData is a byte array then
alg.ComputeHash(userData)
will store the hash within the alg object. Now we can sign the hash of userData using this form of the method:
AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm)

How to get file extension from bytes[]

I'm working on a c# project, I created a method that will receive a file as bytes value byte[] parameter.
Method
public static FileEncryptionModel Encrypt(byte[] Filebytes)
{
//Some code here
}
the question is how can I know the file extension just from its bytes?
thank you.
There is no foolproof way to achieve this. Take a look at the list of file signatures here: https://en.m.wikipedia.org/wiki/List_of_file_signatures
As mentioned here: https://en.m.wikipedia.org/wiki/File_format#Magic_number
Originally, this term was used for a specific set of 2-byte identifiers at the beginnings of files, but since any binary sequence can be regarded as a number, any feature of a file format which uniquely distinguishes it can be used for identification.
Your best bet is to store the file type along with the byte array.
You can try the magic number approach, but how could you know an html file from any other text file?

Persisting text as byte array to flat file

Update
This is to hide my public key on the client side to make it slightly more difficult for prying eyes to get to it. Yes I know the intent of the public key is to stay public but I am trying to mitigate key substitution attacks and in addition to obfuscation, assembly merging, assembly signing and some other measures this is a part of the overall strategy. So in my code that gets shipped to the client side I want to be able to do something like this
string publicKey = #"random characters" //don't want this in the code
byte[] keyBytes = [............] //this should be in the code
I am not quite sure how do I take the text of my public key, convert it to a byte array and then use that in the client code to convert back into public key.
I reckon there is an easy way to do this but I am going round in circles trying to figure it out.
Essentially I have a series of text data which I want to be able to save as bytes to a flat file. I can read it as a byte array but when I use a BinaryWriter to write that byte array to a file I end up with the original text.
Can someone please help?
Just as every file, a text file is a binary file.
It just happens to be that in this case every binary number corresponds with a character, so when you open the file in a text editor, you see readable text.
Obligatory The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!).
You could create a little converter for this purpose.
string publicKey = "AsdfsSDhysffsdfsdfZ09";
Console.Write("byte[] keyBytes = { ");
Console.Write(String.Join(", ", Array.ConvertAll(Encoding.ASCII.GetBytes(publicKey), b => String.Format("0x{0:X2}", b))));
Console.WriteLine("};");
Run it. Then just copy the last line of the output to your source code.

What does the "verify" function in RSAKey (AS3Crypto) does?

I really don't understand what the _verify function does in this class :
http://code.google.com/p/as3crypto/source/browse/trunk/as3crypto/src/com/hurlant/crypto/rsa/RSAKey.as
And especially what does it put into the 'dst' variable. I actually have a "verify key" wich use this method on an encrypted data, and I get the public key in the dst variable...
Here is a small diagram, so that you understand better: http://i.imgur.com/R8DqT.png
Thanks
Ps : I have to do the same in .net,so if you know something equivalent, let me know it
The function _verify (included for reference below)
public function verify(src:ByteArray, dst:ByteArray,
length:uint, pad:Function = null):void {
_decrypt(doPublic, src, dst, length, pad, 0x01);
}
Looking at the link you supplied, the function is used to verify RSA signed data - the result is copied to the dst ByteArray.
Breakdown:
doPublic = function parameter, a wrapper around BigInteger.modPowInt()
src = byte array with signed data
dst = byte array which will hold the result of with verification result
length = length of the data in src byte array
pad = function parameter, a wrapper for pkcs1pad (_encrypt) and pkcs1unpad (_decrypt)
0x01 = padType - an integer value specifying if a fixed value (0xff) is used in padding (0x01) or a pseudo-random one (0x02) - (only actually used in pkcs1pad which is called from _encrypt)
In the RSA scheme, signed data is verified by decrypting the signature using the public key.
Update: Unless you have very specific needs which are not covered, is see no reason why you want to port the ActionScript-3 you posted. Use the c# RSACryptoServiceProvider which is included in the framework. Take special note of the section Interoperation with the Microsoft Cryptographic API (CAPI) in the MSDN description.
Addressing your comments about needing the content of the dst byte array in a similar manner to the AS3Crypto implementation you could just create a wrapper to decrypt the signed data against the public key. Have a look at RSACryptoServiceProvider.ImportParameters() function which you use to import the public key information. Since you haven't provided details as to how the public key is retrieved I can't be more specific. This implementation example should help with parsing key files to create appropriate RSAParameters to feed to the ImportParameters method.

Encrypting Windows Phone Resources at the Bit Level... am I doing this right?

I have a question concerning encryption, more specifically encryption that requires no internet connection (opposed to private / public key or OAuth methods).
The problem arose when I discovered that the WP7 app store is not secure. I won't post a link, but a basic search will yield a desktop application that allows you to download any free WP7 in the marketplace. Then it's a matter of renaming .xap to .zip, and using reflector to look at the code.
I believe that Dotfuscator will solve my problem, but as a learning experience I decided to come up with my own solution.
I decided to have a program that in prebuild gathers the files I want to encrypt, puts them in one file, encrypts that file, and adds it to the project for compilation. Code in the phone app only needs to decrypt the data.
The data I'm encrypting / decrypting is several API Keys (for ~10 web services), meant to be readable as plain text when decrypted.
This is the encryption algorithm (roughly, and with a few alterations) that I came up with:
public static byte[] SuffleData(byte[] data)
{
// Create a bit array to deal with the data on the bit level
BitArray bits = new BitArray(data);
// Generate a random GUID, and store it in a bit array as well
Guid guid = Guid.NewGuid();
BitArray guidBits = new BitArray(guid.ToByteArray());
int guidBitsIndex = 0;
// Iterate over all the data bit by bit
for (int i = 0; i < bits.Count / 2; i++)
{
// if the current GUID bit is true (1), then swap
// the current bit with it's mirror
if (guidBits[guidBitsIndex])
{
bool temp = bits[i];
bits[i] = bits[bits.Length - i];
bits[bits.Length - i] = temp;
}
// Because the data being shuffled is expected to
// contain more bits than the GUID, this index
// needs to be reset
if (guidBitsIndex == guidBits.Count)
guidBitsIndex = 0;
else
guidBitsIndex++;
}
// HideGuidInData hides the bits for the GUID in a hard
// coded location inside the data being encrypted.
HideGuidInData(ref bits, guidBits);
// Convert the shuffled data bits (now containing the
// GUID needed to decrypt the bits) into a byte array
byte[] shuffled = new byte[bits.Length / 8];
bits.CopyTo(shuffled, 0);
// return the data, now shuffled. (this array should
// be the length of the original data, plus 16 bytes,
// since 16 bytes are needed to store the GUID).
return shuffled;
}
I may be shooting myself in the foot posting this, but if it's not known that the data is encrypted using this method, brute force breaking of this takes n! time, where n is the total number of bits in the file. (basically, much, much higher than the probability of randomly guessing a GUID).
Assuming the GUID is well hidden within the file, a brute force attack would take a very long time to figure out.
I spent a lot of time learning about encryption on my way to this solution, and everything I read seemed to be WAY more complicated than this (and, obviously all the things I read dealt with two parties, where encryption can involve a key being passed between them).
What I learned is this:
If the key to encrypting the data is stored with the data, it's only a matter of time for someone to crack it, and get the data
There is no such thing as "perfectly secure". There are varying degrees of success in encryption, and generally speaking, when picking a method of encryption you will want to weigh the importance of the data being secure with the ease with which (considering processor and memory limitations) the data can be decrypted by your program.
I'm thinking that this is too simple to be a good solution. Can anyone prove that suspicion, and explain to me why this isn't as secure as some other methods of encryption? (or make me very happy and tell me this is pretty secure?)
These are the downsides to this algorithm that I can see right now:
The algorithm requires all of the data to be in memory (not TOO worried about this, since I'm encrypting a very small file that's ~500 bytes)
The algorithm requires changing the position of the stream reading the data in order to extract the GUID (basically you can't stream the file from the beginning to the end to decrypt it).
As a note, my application is not really of high importance, realistically it's not likely that anyone malicious will every use reflector to look at my code (realistically it's just people like me who want to know how something works, not do any harm).
This algorithm isn't going to buy you much. Someone who goes to the trouble of downloading your app and using Reflector will have your encrypted data and the code of the decryption process. They could just find your method for decrypting the data, and then use it.
The problem is that you're storing the "encryption key" in the cypher text. There is no way to make that secure when the attacker also has access to the algorithm used. Doesn't matter what crypto system you use.
The basic problem you have is that the phone application itself has to have all the information needed to decrypt and use the data, so anyone looking at the code will be able to see that.
It's the same reason that DRM schemes on DVDs, etc are routinely broken so quickly. Any device, or application, that is able to play DRM protected material has to have the means to decrypt it. Do enough poking arond in memory while the device or app is playing the content and you'll find the decryption key, and then you can crack any similiarly protected media any time you like.

Categories

Resources