For a game I am currently making I am in need of encrypting a variable length string (this could be a short as 10 characters or a full XML document) in C# and then sending this to a PHP script which decrypts and processes the information. I am unfortunately completely in the dark when it comes to cryptography and am having trouble finding something that can suite my needs in this case. Is there a library which can do this kind of variable length encryption across multiple platforms such as this?
AES, sometimes called Rijndael, might be a choice for you. It's a standard created by the National Institute of Standards and Technology, an agency of the US government.
It's available in PHP using the mcrypt extension, and there seems to be a managed library built in to the .Net framework. See this previous SO question for more on C#'s implementation. I know little about C# and .Net, but the answer there has 23 votes, so is likely to be on to something. (Edit: #Fun Mun Pieng's answer contains a reference to AES itself, and might be more up to date or otherwise useful than the post I linked.)
AES is a block cypher, meaning that it operates best on lengths of text of a specific set of lengths. There are multiple operation modes and padding schemes that you'll want to read up on and select. If you use the same operation mode and padding on both sides, you should have perfect interoperability.
Keep in mind that AES is a symmetric cypher. This means that the same key is used to both encrypt and decrypt. It might not be the best choice for you. If your users gain access to the key, the encryption becomes worthless.
Public-key cryptography might be a better choice for you. It uses two keys instead of one. Data encrypted using the public key can only be decrypted by the private key. This means that you don't need to worry too much about the public key falling into the wrong hands, as no data can actually be decrypted about it. It may allow troublesome users to still craft legit-looking messages, though.
PHP's best option for public-key cryptography is the standard OpenSSL extension, which uses the industry standard RSA system. A quick look at Google suggests that there's also native .Net support for RSA as well. Like AES, you may need to worry about modes of operation or padding, but again you should get complete interoperation by using the same methodology on both sides. The one possible annoyance will be initial key creation, and how each side wants to store private and public keys.
For the C# part, you could use the System.Security.Cryptography namespace. Eg:
System.Security.Cryptography.Aes aes = System.Security.Cryptography.Aes.Create();
System.Security.Cryptography.ICryptoTransform enc = aes.CreateEncryptor();
// byte[] input;
// byte[] output = new output[512]
int size = enc.TransformBlock(input, 0, input.Length, output, 0);
I have no idea how to do it for the PHP end, but I'm sure you can find a way to decrypt from standard algorithms such as DES, AES, RSA. And remember to pass the key.
For your case, I guess asymmetric encryption is more suitable.
Related
I need to decrypt a string, returned from an API that was originally encrypted using c# functions based on those here >
http://www.codeproject.com/Tips/704372/How-to-use-Rijndael-ManagedEncryption-with-Csharp
I need to decrypt using PHP.
A password and a key have been provided I've made several attempts to decrypt using openssl_decrypt, but I'm unsure how to use the key in the decryption?
[update] I have been told that the password I have been given is the basis for the iv, and that the padding is PKCS7, the problem is that I have no idea how to create the iv.
I have the following example input/keys, but I'm not sure how to use the password as I've been told it is the iv do I need to pad it to the correct length, if so how?
Original string: 'Mondays Suck'
Password/salt: 'this_is_the_password'
Input key: 'this_is_the_input_key'
Encrypted String: 'mAqsxJaA0jpQdefBPug2tw=='
If there indeed is any ciphertext packing going on, it would be to include the initialization vector (IV), assuming one was even used in the first place.
In short, if I encrypted a string with AES-128:
I'd likely be using PBKDF2 to take a weak passphrase and a salt to generate secret key material used to do the encryption itself.
I'd generate a message-specific (i.e. one-time use) initialization vector for ciphering
I'd then use the secret key [material] and IV generated in the previous steps to encrypt the string using AES-128: E(plaintext, key, iv)
If the string is longer than 16 bytes, I'd have to also use an encryption mode such as CBC, CTR, etc.
For convenience, I would "pack" the IV (not required to be kept secret) in front of the ciphertext by simply concatenating: iv+ciphertext
If I was serious about doing it right, I would generate a message authentication code of the ciphertext and append that as well such that I would now have: iv+ciphertext+mac
On decrypt, I would then verify the MAC before decrypting (if I was to do it right), and I would then need to separate the IV from the ciphertext, and then run it through my decryption routine: D(ciphertext, key, iv).
Another thing to keep in mind is encoding as sometimes we pass around Base64-encoded strings as a more print-friendly format than raw data. You of course would have to decode that before working on unpacking, decrypting, etc.
For academic purposes, I created Crypto Implementation (DRAFT) back when I was teaching myself crypto and wanted to document processes and best practices as well as keep all "moving parts" in view as a reference when I had to work on this stuff. Lots of rules to follow, but all in all, a lot of good learning and professional development opportunities.
Hope that helps some!
Edit: Per my comment below, I just looked at the original source code for the C# implementation. It appears the only way to decrypt this in PHP would be to have a PHP equivalent of C#'s Rfc2898DeriveBytes as this is the part responsible for generating your IV. Study the DecryptRijndael routine and you'll see where it gets the IV from (it basically implies using the same salt). If you truly have no control or influence over the encryption routine, you might be inclined to hack up a solution involving using C# DLLs in PHP and then call the DecryptRijndael method from PHP.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I encrypt a string and get a equal length encrypted string?
I am new to Encryption and Decryption. I have a string which is 24 char length. I need to encrypt and decrypt the word. The encryption may be less secure but I need encrypted word should be same length as input string (24 char). I have searched through web and find some sample Encryption algorithm (AES, MD5). But the encrypted word is too length than input string. This is product key that we will share to customer, so strong encryption is not required. It would be useful if you share sample codes.
Use Vernam cipher. For a single string with a truly-randomly generated key it's theoretically unbreakable. If you start using the same key for multiple strings you reduce its security significantly but apparently you are not looking for utmost security. If you are, you must be able to come up with a different random key for each encrypted password.
Although you can find lots of sample code on the web, I think it would be good practice to you to implement it yourself. It's pretty straightforward.
What you're looking for seems to be Format-preserving encryption, I don't think there are any implementations of this in .NET (I certainly haven't used any). You may need to think up a custom algorithm for this. You say strong encryption isn't required, but you'll obviously need the algorithm to not be obvious. Unfortunately there are literally hundreds of ways you could do this, so it depends on which one suits you.
This seems to be a great post for encryption algorithms
To make the cyphertext the same length as the plaintext, use a stream cypher. This can either be a block cypher in CTR mode, such as AES-CTR, or a dedicated stream cypher, like Rabbit or RC4.
Be aware that you cannot reuse a key for a stream cypher, otherwise an attacker will probably be able to break the encryption. Two cyphertexts that use the same key can be used to eliminate the key entirely, leaving just the two plaintexts.
If you only have the one 24 byte word to encrypt then this is not a problem. If you need to encrypt more than one piece of data, then key management becomes important.
I want to port this simple JAVA example...
AES Encryption/Decryption with Bouncycastle Example in J2ME
...to C# and have the two following 3 questions:
As I understand, the JAVA example uses AESEngine for encryption/decryption operations. What is the difference between AESEngine and AESFastEngine and AESLightEngine? Unfortunately I don't understand the information given in the documentation: http://www.bouncycastle.org/docs/docs1.6/index.html
I want to use a new encryption-key for every file I encrypt. Which block cipher modes of operation should I use: AES.CBC, AES.CFB, AES.ECB OR AES.OFB http://www.bouncycastle.org/docs/docs1.6/index.html
Is my assumption correct that in my case I don't have to use an iv / salt (which means I have to use a static iv?) since I use AES.KeyGen128() for key generation and use it only once?
http://www.bouncycastle.org/docs/docs1.6/index.html
Hope my questions do not cause too much confusion ;-) I but I appreciate every answer, clarification or feedback you can give me.
Mike
My reading of the doc says that the AESEngine, FastEngine and LightEngine all take different tradeoffs of memory versus speed. You would have to test it yourself to determine if those tradeoffs are even relevant in your scenario.
you will need to read up on the various AES modes. Different modes have different strengths and attributes, which may be more or less applicable or desirable depending on your scenario. So the answer to your question is "it depends."
no. you will need an IV. As far as the salt, it is usually employed with the passphrase to generate the actual encryption key and the IV, often via PKBDF2. That is outside the realm of AES, but it is a typical usage.
Finally you didn't ask, but.... why are you porting that code to C#? .NET has AES encryption built-in. You don't need to port anything, you can just use the .NET base class library. Just ensure you use the same keysize and mode, and make sure your key+iv is the same on each side, and the .NET BCL AES classes will interoperate with the BouncyCastle stuff for J2ME.
I've found a few answers to Encrypt in PHP, and Decrypt in C#, but as yet have been unable to reverse the process...
The background is I want to:
In C#:
AES encrypt a file's contents.
Upload the data (likely via http via POST) to a server.
In PHP:
Receive and save the file.
And in PHP (at a later date):
Decrypt the file.
I specifically want to encrypt it outside of using SSL/TLS (though I might have to do this as well), as I need to know the file remains encrypted (and decryptable!) when stored on the server.
To encrypt in C# I'm using:
Rijndael RijndaelAlg = Rijndael.Create();
RijndaelAlg.KeySize = 128;
RijndaelAlg.Mode = CipherMode.CBC;
CryptoStream cStream = new CryptoStream(fStream, RijndaelAlg.CreateEncryptor(Key, IV),
CryptoStreamMode.Read);
and to decrypt in PHP:
mcrypt_cbc(MCRYPT_RIJNDAEL_128, $key, $buffer, MCRYPT_DECRYPT, $iv);
Generally it only depends on selecting the right options on both sides:
Plaintext character format
how plaintext characters are encoded in the bit string
Padding
how to pad the plaintext to be an exact multiple of the block size
Key length
must be agreed if there is a choice
Key derivation
how to create the bit string to be used for the key
Mode
which mode of encryption to use
Storage format
how we store the ciphertext
Please see here for a lot of information about these things. Especially the padding seems to be the root of most interoperability problems as PHP's mcrypt uses a NULL-padding by default and has no built-in support for any other padding mode, while e.g. .NET doesn't even provide an option to use a NULL-padding (as it may cause issues when encrypting binary data).
I know this was asked a while ago but I thought I'd post my solution for others. I wrote up a quick code example in PHP and C# that lets you encrypt/decrypt both ways. I had a few issues with getting the settings on both sides to work out. A difference in padding would let it decrypt one way but not the other
https://github.com/dchymko/.NET--PHP-encryption
hope that helps some people.
Are you using the same mode with both? I.e. are you using CBC with both (and not ECB). If you don't understand what I just said then drop a comment and I'll explain in detail, as it has fairly major security repercussions.
I had a similar problem a few months ago - I had a project that had to use AES encryption and I had to make sure that the exact same algorithm is used between a C# and A C++ component. I ended up implementing a shared DLL library used by both based on the AES crypto wrapper from this codeplex article:
http://www.codeproject.com/KB/security/WinAESwithHMAC.aspx
i want to encrypt string in java and decrypt the same string in C# and vice versa .how to do it .and which is best encryption method
Thanks
aswan
You need to go with a standard encryption method. The algorithm used will be secure, the result will be portable and there are libraries for many platforms. 3-DES or AES would be good choices.
The word "best" is different things to different people, and strongly influence the choices available to you.
If speed is extremely important to you, then just add one to every character value, send it, and subtract one again. In other words send "ABC" as "BCD".
AES is supported in the .NET framework in the Rijndael class, you can find the documentation on MSDN http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx. When encrypting a string you will want to make sure that the way you choose your key is a secure method, and make sure it is stored in a secure place as well. In any encryption scheme the weakest link is the key.