Is this a bad encryption practice? - c#

So I am trying to encrypt my files and authentication password.
I am currently using (A)Password Derived Byte[], (B)Clear Byte[] and a strong (C)string to encrypt it.
In my program, I hardcoded the (A)Password Derived in there. I also harcoded a (B)Encrypted version of Clear Byte[] and a (C)Encrypted version of string.
To decrypt my file/password, I must:
1. Decrypt Encrypted version of (B)Clear Byte[] using (A)Password Byte.
2. Decrypt Encrypted version of (C)String using (A)Password Byte.
3. Use the (B) Clear Byte, (C) Clear string to decrypt the file/password.
If this is not a good practice, could someone please provide me suggestions/methods I should use ?
I am developing it in c#

If you want something that only your program can read then you should use DPAPI. In C# This is wrapped up in the ProtectedData class.
Your code is not safe, the code could easily be reverse engineered and decrypted. Using DPAPI means that only your user can access the data you protect in your application.
You use the protecteddata class like this:
ProtectedData.Protect( data, s_aditionalEntropy, DataProtectionScope.CurrentUser );

I decided to go with my own approach mentioned above because no one was able to post a answer I could use.

Related

Why is crypto with .Net Framework so complicated?

In most cases I need to encrypt a string with a password and then send/save it somewhere. Later I want do decrypt it with the password. I am not encrypting nuclear missile codes or medical patient data! The ideal would be 2 functions:
string Encrypt(string plainText, string password);
string Decrypt(string cipherText, string password);
I had a look at the crypto documentation... Oh boy! So I try to code the above calls myself (see a proof of concept using AES Managed and Base64 encoded payload). I am no crypto expert, why do I have to code that? I probably did somethings wrong...
To derive the key from the password the interface requires a salt. Can I use the password as salt? Can I re-use the IV as salt? Maybe not, but I don't want to add another parameter.
Can I use a fixed IV? Same plaintext and password should result in different cipher text, so I have to supply the IV for decryption in the payload.
Can I use a salt for the key and keep the IV constant instead? Feels wrong.
Creating a nonce and deriving IV and key salt from it is a valid approach?
If .Net would support the GCM mode would I still have this problems?
The .NET crypto API exposes a general purpose encryption library, containing object oriented approaches to implement cryptographic algorithms. Of course, to use these algorithms and algorithm implementations you need to have a good grasp on cryptography, which you currently lack.
This general purpose library is required to implement the various protocols that exist out there. Usually a single algorithm doesn't fulfill a specific use case (encrypt a string using a password, returning a different string, in your case). So a protocol needs to be chosen or devised that does fulfill that use case. This protocol may e.g. define a container format such as CMS or PGP, which can for instance be used to encrypt emails (the use case).
You're directly trying to apply cryptographic algorithms to solve your use case. That's not going to work. You need a pre-made protocol, preferably with a pre-made API.
Note that there are many different use cases, many different protocols and even more opinions on how to create and implement those correctly. Libsodium / NaCl for instance defines a small container format called SecretBox that does take some of the work from you.
However, it would of course be rather impossible to implement TLS on top of NaCl, as the functionality / algorithms are just not there. Again, .NET needs a generic crypto library like the .NET API for others to implement their protocols.
So either you'll have to byte the bullet and try to create your own protocol or you take an existing one and take an educated guess if it is secure (hopefully the protocol has been reviewed / updated a few times). Stay away from single person projects without additional contributors (like the many sample codes out there without review).
For your own protocol, yes, there are mistakes such as not storing the salt with the ciphertext. You need a random - or at least unique - salt to be secure, reusing the password for that is certainly not secure. Don't let it become a single person project itself and either borrow a protocol or have it reviewed.
OK, quickly then:
To derive the key from the password the interface requires a salt. Can I use the password as salt? Can I re-use the IV as salt? Maybe not, but I don't want to add another parameter.
No, the salt needs to be unique and preferably random; the password / salt combination should be unique (it should not repeat, not even in time, or over different domains).
Can I use a fixed IV? Same plaintext and password should result in different cipher text, so I have to supply the IV for decryption in the payload.
No, unless the key changes value each time (see above). For CBC the IV should be unpredictable unless you use a fresh key each time.
Can I use a salt for the key and keep the IV constant instead? Feels wrong.
That's possible, as long as you don't repeat the salt.
Creating a nonce and deriving IV and key salt from it is a valid approach?
That depends on very specific details. In other words, I would not try it if you don't exactly know what you're doing.
If .Net would support the GCM mode would I still have this problems?
Absolutely, and in a sense your problems would be worse if you'd use GCM, as using GCM with the same key and IV is completely broken.
Remember, GCM is just an algorithm, not a protocol, it cannot solve your use case by itself.

C#: Best practice for obfuscating password in text file?

Firefox has to store passwords. That is totally unsafe, but it has to do it, that's all.
My C# app has the same requirement (it is a kind of browser).
Rather than storing passwords in plaintext, Firefox obfuscates them a bit.
What is the best practice for this kind of obfuscation?
For instance, here is Firefox's strategy, if I understand well:
Create a salt for the app's user
For each password, use the salt in a symmetric transformation when storing/retrieving
Store the passwords file in a directory named after the salt.
Is my understanding correct?
Is there any better strategy, or even a C# library for this?
Similar questions for other programming languages have unsatisfying answers, they don't not go as far as Firefox, just suggesting rot13 or base64, which makes it easy for automated malware to identify obfuscated passwords in unknown software. (just searching for the base64 value of common passwords)
Once again: it will not resist to any attacker, I know. But if Firefox cares I should too.
You should use the ProtectedData class to encrypt the passwords.
You can specify DataProtectionScope.CurrentUser to encrypt data using the current user's Windows login password, so that no other user can decrypt it (this also works if the user has no password)
It would probably be easiest to use an encryption rather than obfuscating. Obfuscating code generally makes it harder for someone to identify what is what in code if they viewed the source. If you don't encrypt the information however, people can still figure it out.
My advice would be is to use AES-256 or Tripple DES-128 Encryption.
Easily, you could have the passwords stored in a text file and then encrypted. Only then through your browsers can the file be decrypted.

How to decrypt TrafficScript encrypted value

We are using TrafficScript running under a Stingray Traffic Manager to encrypt a string and store that encrypted value in a cookie. Like so:
$encrypt = "string to encrypt";
$passphrase = "passphrase";
$encrypted= string.base64encode(string.encrypt($encrypt, $passphrase));
http.setResponseCookie("encrypted", $encrypted, "path=/");
What I'd then like to do is decrypt that cookie value in C#, however, I've not been able to achieve it thus far. I suspect this is because the exact details of the algorithm used by the TrafficScript isn't documented fully. The reference guide states:
string.encrypt( string, passphrase ) - Encrypts a string using the provided pass phrase. The returned string is encrypted using the AES block cipher, using an expanded form of the passphrase as the cipher key. A MAC is also added to ensure the integrity of the string.
I've tried AesManaged but get an exception 'Length of the data to decrypt is invalid'.
Can anyone provide any pointers?
I didn't manage to find a way to do this purely with TrafficScript.
So I ended up writing a Java Extension and running that from inside my TrafiicScript rule. It was made possible by reusing some code posted in a blog by Joseph Ssenyange which details how to write cross platform encryption for Java and C#.

encryption in .net

I was told that there's an encryption library I can use and there's a couple that I can choose from (eg. AES, RSA, etc). I also read something about keys. Are keys something you just generate so you can encrypt and decrypt a series of texts? Do you have to purchase that key?
Also, is there a best practice that I need to be aware of in encrypting and decrypting? Is encrypting a password recommended? Would performance be affected?
You are correct. Base64 encoding is a world away from actually encrypting your data. The former simply converts the data to be representable using 64 unique characters, obfuscating the data at best, while the latter actually converts your data into a representation that can only make sense once it is decrypted using the proper key. Do not ever base64 encoding if you want to keep something a secret.
Are keys something you just generate so you can encrypt and decrypt a series of texts?
Yes.
Do you have to purchase that key?
No, you generate the keys yourself.
Is encrypting a password recommended?
Most definitely. You should always encrypt passwords whenever possible.
Would performance be affected?
When encrypting data, you're using more CPU cycles than you would have otherwise, so performance is affected, but it really depends on what algorithm you use, the amount of data, etc.
Here are some linke that might help you out:
Some info on encryption in .NET
MSDN Article
More on Encryption
Start reading here:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.aspx
Oh and yes - encrypting a password is recommended in most systems (do a search for hash and salt).
A common practice would be using Protected Configuration feature.
Encrypting and Decrypting Configuration Sections

Encryption/Decryption in .NET

I'm looking for a secure way to encrypt and decrypt a string in a Visual Studio Project (in C#). I found that there is native DES classes, but it's not secure enough. Do you have any suggestions?
UPDATE :
OK then, the question is : What's the most secure way to encrypt/decrypt a string without too much hassle (aka having to install external tools, etc. An external library is fine though). And where to put the secret "key" (is compiling the value inside the code secure enough?).
Update #2
If I'm using something like this code to save encrypted string in a config file :
using System.Security.Cryptography;
using System.Security;
byte[] encrypted = ProtectedData.Protect(StrToByteArray("my secret text"), null, DataProtectionScope.LocalMachine);
byte[] derypted = ProtectedData.Unprotect(encrypted , null, DataProtectionScope.LocalMachine);
Is this secure enough? I guess that with the "LocalMachine" parameter instead of "User" parameter, somebody could just write an application in .net, put it on the machine and execute it to decrypt the encrypted string. So if I want it more secure, I'll have to have a config file different for each user? Am I understanding that correctly?
To answer your second question, no, storing the encryption key in the executable, even obfuscated, is not secure at all. It'll keep casual prying eyes out, but not those with an hour to devote to walking through your decompiled source.
Think hard about where to store your encryption key - it looks like that'll be your weak point. And yes, this is a hard problem to solve. The most secure way to store encryption keys is not to - require the user to type a password, or require external hardware, like a key fob.
If you're encrypting contents intended to be read only on a single machine or by a single domain user, consider the Data Protection API (DPAPI). It takes the encryption key out of your hands - it uses the user's Windows credentials as the key.
I've got a little more detail in another answer here: Persistent storage of encrypted data using .Net
Regarding your second edit (is DataProtectionScope.LocalMachine good enough?); this MSDN blog entry summarizes it well:
Setting a scope of
DataProtectionScope.CurrentUser
encrypts the data so that only the
currently logged on user can decrypt
it. Switching to
DataProtectionScope.LocalMachine
allows any process running on the
current machine to decrypt the data.
This could be useful in a server
scenario, where there are no untrusted
logins to the machine, but for a
general purpose workstation using
LocalMachine encryption is almost
equivalent to using no encryption at
all (since anybody logged in can get
at the data).
It also has AES.
If I read your update correctly, you basically want to conceal some string constant from a sysadmin snooping around your assembly.
There is no way to make it impossible that someone with too much time extracts your string constant eventually. But you can annoy them, hoping that they give up trying before they unmask your secret.
One way to achieve that are Obfuscation Tools. These obfuscate your compiled assembly as much as possible, making it much harder to follow program flow when decompiling it with Reflector. Try it. If your string constant is still not hidden enough, you can additionally invent your own scheme to make it harder to find.
If you need more security, the almost only option is to not give the relevant parts of the code to the user. Create a web service that contains the secret parts of your application and secure the connection with SSL/TLS.
Try using AesManaged.
That depends on your definition of secure enough. You may use triple DES. .Net also has native Rijandel class. Is it secure enough? http://www.obviex.com/samples/Encryption.aspx
Using a well tested and accepted library is a good idea too...
http://www.bouncycastle.org/csharp/

Categories