Initialization vector - DES/triple-des algorithm - c#

In order to generate the encrypted data we would need to define a Key that should suffice generating the data. But in .net DESCryptoServiceProvider requires Key and Intialisation Vector to generate the encrypted data. In this regard, I would like to know the importance & the benefit gained by defining this initialisation vector field. Is this mandatory while encryption using DES algorithm.
Pls share your thoughts on the same.
Regards,
Balu

If a key is used to encrypt multiple items that happen to be the same (or start out the same) without an initialization vector, you'll get the same ciphertext output, which is a pretty big problem.
Using a unique initialization vector for each item that's encrypted solves that problem.
See http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Initialization_vector_.28IV.29 for a bit more detail.

Related

Decrypting Magtek EMV Data

basically my question is more of a "how should I approach this" than more of a code example based question....Basically I am trying to decrypt the Tag DFDF59(encrypted data tag) from a Magtek eDynamo EMV dip which has data like encrypted track 2 that I need. I am using tag DFDF56(KSN) to decrypt the data from the onTransactionResult callback. using https://www.magtek.com/content/documentationfiles/d99875728.pdf as reference. Magtek MSR works great, I can decrypt encrypted track 2 fine and I can see the clear text, it is just EMV that I am having issues with. With MSR, I basically pass in the encrypted data and the KSN into DUKPT and a clear text string is returned. Attempting to do the same with That EMV Tag but does not seem to be working. Any suggestions on how to approach this? Maybe I am not using the right Tag or not the proper KSN?Do not have much experience with EMV decryption
has data like encrypted track 2 that I need
If data is encrypted then there will be a key that will decrypt it.
It can be TDES - Triple DES + ECB Mode operation to decrypt the data ( Generally it works in EMV).
Maybe I am not using the right Tag or not the proper **KSN** ?
Try to get the correct/plain key to perform this operation, Please make sure you are using the correct key otherwise result is false always.
Hope it helps.

RandomNumberGenerator vs Aes generate key. Which should I use to get myself a key when using AES encryption (C#)

So I was checking some implementations online and I noticed that some people use the following way to generate a key:
using (var random = RandomNumberGenerator.Create())
{
var key = new byte[32];
random.GetBytes(key);
}
While others use the generateKey method which is built in the AES class:
using (Aes myAes = Aes.Create())
{
myAes.GenerateKey();
var key = myAes.Key;
}
Both of them are in the System.Security.Cryptography library, just wondering if there is an actual difference between them and if yes which one should I go with?
Both versions do the same thing. Aes.GenerateKey will use the same RandomNumberGenerator.Create() as first example to generate new key.
However I'd prefer to use second version, because:
1) It expresses intent very clear. You are generating AES key, not just arbitrary random byte array.
2) AES can have different key sizes. Not only that, but some key sizes are invalid for AES. First example now generates 32-byte keys only. If you modify it to accept key size - someone can pass invalid (for AES) key size to it. So you will need to validate passed size to verify it's a valid key size for AES. But why do that if Aes class already does that for you?
Side note: there is no need to call GenerateKey, though it does not harm too. If there is no key yet - it will be generated when you first access Key property.
Good question. Both use the same underlying CSPRNG. The results are equally secure.
You can view this in the .NET Reference Source

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.

Iterative / Additive MD5

I need to generate a checksum over a dictionary. Keys and Values.
Is there any simple way to accomplish this in an iterative way.
foreach(var item in dic.Keys)
checksum += checksum(dic[item]) + checksum(item);
In this case, keys and values could be converted to strings, concatinated and then a single checksum applied over these but is there a better way?
Ideally MD5 but other options could work. Using this to validate data that is passed over a couple of storage methods. The checksum is then encrypted along with some other information (using AES) so I am not horribly worried about an ideal, unbreakable checksum.
Generating a signature is pretty much the same process all over: create a MD5 hash object, then you digest all the bytes of interest, then you extract the hash value. The important thing is that you and the verifier agree on the bytes to hash and on the order they are hashed.
In C# you can achieve this by calling HashAlgorithm.TransformBlock repeatedly, and then finally calling HashAlgorithm.TransformFinalBlock. This is automated by using a CryptoStream with a HashTransform (MD5 implements ICryptoTransform) and then simply writing your dictionary into the crypto stream.
As aside note, countless protocols and crypto schemes that digest a hash and encrypt it were humiliated in the wild. I would suggest taking the beaten path and use well established industry standards::
Use a HMAC, see HMACMD5
Use an RSA signature (ie. private key encryption of an MD5 hash), and save your self from all key provisioning and master secret exchange problems, see RSACryptoServiceProvider.SignHash
Answered my own question I think....
GetHashCode() on each item. Add them in an unchecked {} environment. Too simple.
You should not be writing any new code relying on MD5. It's deprecated, and for some extremely solid reasons. You should look at SHA-256, or at the very least SHA-1, instead
And you should take Remus' advice. Cryptography + hashes = digital signatures. Pull something down off a shelf (just not XML-Security, please!), learn it, use it, and get on to other interesting parts of your project.

Byte encryption ( DES-CBC zero pad )

Currently writing my own AMF TcpSocketServer. Everything works good so far i can send and recieve objects and i use some serialization/deserialization code. Now i started working on the encryption code and i am not so familiar with this stuff.
I work with bytes , is DES-CBC a good
way to encrypt this stuff? Or are
there other more performant/secure
ways to send my data? Note that
performance is a must :).
When i call: ReadAmf3Object with the decrypter specified i get an: InvalidOperationException thrown by my ReadAmf3Object function when i read out the first byte the Amf3TypeCode isn't specified ( they range from 0 to 16 i believe (Bool, String, Int, DateTime, etc) ). I got Typecodes varying from 97 to 254? Anyone knows whats going wrong? I think it has something to do with the encryption part. Since the deserializer works fine w/o the encryption. I am using the right padding/mode/key?
I used: http://code.google.com/p/as3crypto/ as as3 encryption/decryption library. And i wrote an Async tcp server with some abuse of the threadpool ;)
Anyway here some code:
C# crypter initalization code
System.Security.Cryptography.DESCryptoServiceProvider crypter = new DESCryptoServiceProvider();
crypter.Padding = PaddingMode.Zeros;
crypter.Mode = CipherMode.CBC;
crypter.Key = Encoding.ASCII.GetBytes("TESTTEST");
AS3
private static var _KEY:ByteArray = Hex.toArray(Hex.fromString("TESTTEST"));
private static var _TYPE:String = "des-cbc";
public static function encrypt(array:ByteArray):ByteArray
{
var pad:IPad = new NullPad;
var mode:ICipher = Crypto.getCipher(_TYPE, _KEY, pad);
pad.setBlockSize(mode.getBlockSize());
mode.encrypt(array);
return array;
}
public static function decrypt(array:ByteArray):ByteArray
{
var pad:IPad = new NullPad;
var mode:ICipher = Crypto.getCipher(_TYPE, _KEY, pad);
pad.setBlockSize(mode.getBlockSize());
mode.decrypt(array);
return array;
}
C# read/unserialize/decrypt code
public override object Read(int length)
{
object d;
using (MemoryStream stream = new MemoryStream())
{
stream.Write(this._readBuffer, 0, length);
stream.Position = 0;
if (this.Decrypter != null)
{
using (CryptoStream c = new CryptoStream(stream, this.Decrypter, CryptoStreamMode.Read))
using (AmfReader reader = new AmfReader(c))
{
d = reader.ReadAmf3Object();
}
}
else
{
using (AmfReader reader = new AmfReader(stream))
{
d = reader.ReadAmf3Object();
}
}
}
return d;
}
Define "secure."
DES is more secure than plain text, but due to it's 56-bit keysize, it's not usually used anymore. If you're protecting data against your family, or the casual ease dropper this might be okay.
If people are using DES these days, it's Triple DES which essentially runs DES, three times, on each datablock.
Now a days the symmetric encryption algorithm (which DES is) of choice is AES, which is like the spiritual successor to DES.
AES with a sufficiently large key of 256 (really 512 or higher now a days) is cryptographically secure for most applications.
The few caveats of AES are:
It's still restricted to US Export controls
The NSA can decrypt your information if they want to (yes
this is tin hat thinking)
Regarding your error, first try switching to AES, and see if you still get a problem.
Regarding AES:
Key selection is important, as well as key protection.
Key Selection
If you want to "password" protect your data, using AES, then you need to convert your password into an AES key. This is a common pitfall for many amateur computer security developers. Adobe essentially destroyed all the protection of AES in their PDF's by using an MD5 hash of the users password as the key. Needless to say, you're smarter than all of Adobe's engineers combined, so you won't make that mistake.
The proper way to generate a key from a password is using RFC2898 aka PBKD2 (password based key derivation function). .NET handily has a method that does this: Rfc2898DeriveBytes(). Essentially what this does is cryptographically securely hashes your password, with a supplied salt (more on this in a bit), a number of times, supplied by the user. This provides several layers to protect against brute force attacks against your password (assuming your key is large enough to prevent brute force attacks against it!)
Each iteration of PBKD2 takes a minuscule amount of time to run. The more interation you run (i think the recommend number is > 1000), the more computer time it takes. This time is still less than a human would recognize, but in computer time it's like a century. Thus without knowing the exact iteration count, it makes it a very lengthy process to brute force attack a password.
Salt. Rather than taking a direct hash of your password, a salt adds extra information to your input password, creating a unique hash. This prevents rainbow table attacks, assuming you keep your salt value protected.
Key Storage
The other side to cryptography is key storage. If you are password protecting your data, then you need to securely store the password. The easiest way is to use the OS's built in security. On Windows thats using DPAPI in the registry, and Unix, filepermissions.
AES as a Session Key
If you are looking to securely transmit data across a nonsecure channel (or even adding your own extra security ontop of SSL), you may want to looking at using AES as a session encryption.
Essentially this is two scheme encryption system that works as follows:
You generate a public/private key pair using your favorite assymetric encryption (RSA!) for your server.
Each trusted client is given the public key.
During a session, the client generates a new random AES key of 256 bit or higher.
This AES Session key is encrypted using the public RSA key.
This encrypted data containing the AES session key is sent to the server.
The server decrypts the data using it's private RSA key, and keeps the AES Session key.
During the rest of the session, all data is encrypted with the session AES key.
At the end of the session, the AES key is discarded.
While this does require more handshaking, this gives you the added protection of limiting exposure. Since the AES key is only good for a session, if it's discovered, the damage is only limited to a single session.
DES is a block cipher, so in general it makes working with bytes more tedious. AS3 is a stream cipher used primarily with GSM phone systems, because it's a stream cipher it'll work nicely with bytes.
Personally, I would use RC4 if you really need to use a stream cipher; it's very quick. There's a good implementation here http://dotnet-snippets.com/dns/rc4-encryption-SID577.aspx
There are some very important caveats you should be aware of when using stream ciphers:
1) NEVER re-use an encryption key with a stream cipher.
2) Because you're encrypting one byte at a time, it's hard to determine if the data has been tampered with, so you'll need add a digital signature or HMAC to the stream.

Categories

Resources