I am looking for a way to do private key encryption in C#.
I thought I could use the RSACryptoServiceProvider, but it only supports public key encryption.
The only thing I found on the subject was this project, but I would rather use something I can find in .net: http://www.codeproject.com/KB/security/PrivateEncryption.aspx
Please note I am not looking for signing.
Please note I require asymmetric encryption.
Any idea's?
Background story:
I am sending an encrypted file to another system which is running an application. The encryption is making sure the file cannot be altered (more or less) or viewed by anyone. The application is able to decrypt the file using the public key and do something with it.
I know pretty much anyone is able to get the public key from the application, this is not a problem in this case.
The encryption is making sure the file cannot be altered or viewed by anyone
Public Key Encryption - when done "by the book" - seperates encryption and signing ("cannot be altered"). In your case, use two key pairs, one within the application and one at your site. Encrypt the file using the public application key and sign the file using your private one.
This is a really widespread usage, I even like to call it "Best practice". As for the downvote, I can only guess that ruling out signing in your question triggered this.
It should not be done. Sign instead and use symmetric encryption.
Related
Any body sees anything wrong in using sn.exe to generate a public / private key pair that I can later use to encrypt data using the private key, then give people the public key so they can decrypt my ciphertext? I know sn.exe is used for strong naming assemblies, but since it generates a key pair, can I simple use this scheme?
I am asking this question knowing that RSA is meant to encrypt with the public key. But I have what I believe to be a valid use case for doing the opposite.
This is really two questions:
Should you use sn.exe to generate your keypairs?
Should you use a private key to encrypt data?
The answer to the first question is: no, not really. SN.exe's keypair generation is really only useful for very small development environments, and requires you to handle ALL security. There are much better ways to generate certificate containers that include things like password protection (PFX). Take a look at the MakeCert tool, for example - it can be used to generate self-signed X.509 certificates that can be used for pretty much all cryptographic operations you may want to perform.
Unfortunately, the answer to the second question is also: no, not really. From a crypto standpoint, there's not much point to encrypting something with the private key; after all, the public key is just that: public. If anyone can decrypt it (No OS provides any protection of public keys, so it's trivial to get a copy), there's not much point in encrypting it. If the intent is to ensure that people can prove it's from you, a digital signature is a better way to go, and in such a case, what you describe is exactly what you'd want to do: sign it with the private key, verify the signature with the freely available public key.
Now, if your intent is to have a way to distribute encrypted data to multiple recipients, consider using a PKCS #7/CMS envelope. Since you're talking about using sn.exe, that tells me you're using .NET, so you're in luck! The EnvelopedCms class should provide what you need. All you need are your recipients' public keys from their X.509 certificates (makecert to the rescue!). MSDN has a walkthrough here.
i am planing to write a C# class library which will include my encryption algorithms like RC4, DES. These are single key encryption algorithms.
Now i want the best secure decision to protect my key. Should i put my key hardcoded inside the DLL or should i set my key from my external application which uses the DLL? Which one do you think is more secure when you consider the decompling tools?
Loudly thinking:
if the key is hardcoded in my security library and someone find the DLL and import it to his C# application, can he easly decode my chipper data?
if the key is not hardcoded in my security library but is set from my external application, someone needs to decompile also my external application to find my key?
Setting the key values from my external application which will use the security DLL seems more secure to me. What do you think?
Thanks.
Hard Coded Key
If you include the shared/private key in the DLL, then anyone who has a copy of the DLL will have a copy of the key. If your model is to share your application with multiple users, all users will have the same encryption key, and can decrypt anything encrypted by another user. If your application is easily available, then you have to assume the attacker has the application (and therefore the key) as well.
It also means that all developers will have access to the production encryption key, since they have the source code. QE will also have access, as they probably have access to the binary. Either of these two insider groups will be able to decrypt anythign that your application protects for your customers.
Is this what you want? It's generally a bad practice, but it's worse in some environments than others. For example, if you're writing code to learn how to write crypto and nothing more, it probably doesn't matter - just make sure nobody else can use it :) If you're writing a service, it's a bad practice and introduces risk, but it's not the worst thing you could do. If you're writing something that will be shared to multiple customers, then you defeat the purpose of encrypting by including the key in the binary.
And it's not really that hard to generate random data (using a cryptographically strong random number generator), store it in a file, and use that file as your encryption key. My recommendation is go with the separate key.
Separate Key
If you ship the key in a separate file, you eliminate all the risks introduced by shipping the key in the binary but you introduce others. Or, stated differently, now that your crypto can do some good, you need to make sure you do it right or it'll still be useless.
The key needs to be generated using a cryptographically strong random number generator, so that it's not predictable. The key needs to be stored securely - the whole path to the key file needs to be protected, and you should consider using a password protected store (like a keystore) to ensure that only users with the right password can access the key. Of course, that last one depends upon your deployment model, and if you need unattended restart. And the key needs to be used securely - constant order operations, don't act an encryption or decryption oracle, verify integrity of data before semantically parsing it, etc.
I'm looking for a way to securely store an API key in a WP7 application. The key is a string and is currently hard coded into the code (see below). I know that someone with a reflector program could easily view this. Is there a better way to package this key as part of my app? Would a resource be more secure?
string key = "DSVvjankjnersnkaecjnDFSD44VDS23423423rcsedzcadERVSDRFWESDVTsdt";
Thank you in advance.
Have a look at Safeguard Database Connection Strings and Other Sensitive Settings in Your Code, it is a good read. Your question is under the "Hiding Keys in the Application Source Code" section.
Excerpt:
If you define the key in the application, in addition to obfuscating the assembly, try not to store the actual key bytes in the source code. Instead, implement key-generation logic using persistent characteristics, such as the encryption algorithm, key size, pass phrase, initialization vector, and salt (see an example at Encrypt and Decrypt Data Using a Symmetric (Rijndael) Key). This will introduce an extra layer of indirection, so the key will not be accessible by simply dumping the symbols from the application binary. As long as you do not change key-generation logic and key characteristics, the resulting key is guaranteed to be the same. It may also be a good idea not to use static strings as key-generation characteristics, but rather build them on the fly. Another suggestion would be to treat the assembly the same way as the data store should be treated, that is, by applying the appropriate ACLs. And only use this option as a last resort, when none of the other data protection techniques work and your only alternative is leaving sensitive data unencrypted.
I've read through all these answers, and I don't think there is any way you can securely embed this - regardless of where you put it, or how you obfuscate it. As long as its in your XAP and decoded within the application then it will always be available to hacking.
If you need to ship the key inside the xap with a reasonable degree of protection, then I think #maka's answer yields your best bet - obfuscate it as best you can - but don't think this will make you secure - i.e. don't do this for your mobile banking apps!
Alternatively, if you really need security then don't operate solely within the app - use a web server as well. For example, if you were doing a Facebook app and needed to somehow protect your facebook secret key, then you would need to redirect the user from your app to a web page on your server for authentication. That web page would then need to guide the user through the process of getting an access token - and then just that access token (along with the public appid) would need to go back to your app. And for those webservices which require knowledge of the secret key to accompany every call, then I'm afraid every single call will probably need to go via your server.
You can encrypt Api key with ProtectedData and then decrypt it in runtime. This is good tutorial how to encrypt data in Windows Phone: Encryption in Mango
May be you can encrypt it before hand and save it in app.config. And while reading it decrypt it using the same algorithm.
You could use DotFuscator to disable the ability to use reflector.
But, this will not allow you to change the key without recompiling.
In the past I've used the following method in other (web/winform-based) software:
http://weblogs.asp.net/jgalloway/archive/2008/04/13/encrypting-passwords-in-a-net-app-config-file.aspx
It's not an answer maybe, but sure it's a suggestion:
Store encrpyted key in a db. And store encrypted "db password" in app.config.
Use two proper string encrypt/decrypt algorithm, let's say algorithm x and y.
Put encrypted db password in app.config before to publish it.
Decypt app.config password(algo y) to connect the db for taking new encrpyted string(real one).
Close the connection and decyrpt new string with algorithm x if reflector/etc. not running.
Use it.
Dispose the object that holds the string.
I am developing a C# app that can NOT connect to the internet.
This app will produce a configuration file for my hardware.
what i want to be sure, is that when i give the configuration file to my assistant he doesn't change it and puts in the hardware a file with different configuration.
To avoid this i am currently using a simple method.
In the code i've a key: abcd123
My application produce a configuration file and then:
HASH the configuration file and encrypts the HASH with the KEY: abcd123 stored in the
string variable KEY
give the configuration file to my assistant who loads it in the hardware
now, the hardware has the KEY abcd123, it decrypts the config and HASH the payload. IF the 2 HASH are THE SAME i assume that my assistant did not change the configuration file.
What i am concerned about is that the KEY store in the code in .NET is very easy to recover without obfuscation.
I've thus bought Crypto Obfuscator, but i don't know how much my key is secure.
I am not skilled enough to de-compile my program and see if the key is still in clear or not.
What methods can you suggest me to make me REASONABLY secure that my key is "safe" ?
I understand that a there is no way to secure it, but i just want a reasonable additional security to my automated obfuscation of which i dont know much.
I hope i've been clear but ask for clarification.
what i want to be sure, is that when i give the configuration file to my assistant he doesn't change it and puts in the hardware a file with different configuration.
You are looking for a digital signature algorithm. Broadly, there are two ways to do this:
Use a symmetric algorithm that computes a crypto-reliable hash (SHA-2 for example). You publish hash and corresponding file. Hardware gets the file, computes the hash with the same algorithm and asserts that it is the same as the publicly published hash. See how Apache log4net provides libraries and the matched signatures.
Another approach would be to use a public-private key signature, for example with RSA. A sample is available from msdn, where it shows how to sign an XML document using RSACryptoServiceProvider. You can create a private-public key pair. Private key is used to create a digital signature and you keep it to yourself. With public key you can only verify signature, and this is what you deploy to the device.
Another safety tip from the link above:
Never store or transfer the private key of an asymmetric key pair in
plaintext. Never embed a private key directly into your
source code. Embedded keys can be easily read from an assembly using
the Ildasm.exe (MSIL Disassembler) or by opening the assembly in a
text editor such as Notepad.
You can only get real security if you don't put the key in your code.
One way to do this is to use public key cryptography (for example RSA).
You create a public and a private key. The private key neverleaves your system.
You use the private key to sign the config file.
The software running on the hardware contains the public key and uses it to verify the signature of the config file without any need for a network connection.
Even if the whole world knows your public key nobody can create a valid signature without the private key (which is only available to you).
I'm adding some encryption methods to a class library (C# 2.0) and would like to know the best place to put the pass phrase, salt value and initialisation vector required. Is it a really bad idea just to hard-code these into the DLL, or should I be be encoding them and storing them somewhere else?
Thanks.
Edit: Further info - encryption required for personal info in database (addresses, phone numbers etc..), no bank/medical type info so solution doesn't need to be too hard-core. Class library will be used on a server for a web-app, encryption methods to be used in the data layer.
If you hard-code you initialisation vector and key into the DLL, then you really may as well forgo encryption altogether. If you could tell us a bit more about the reason you're using encryption here and how the data needs to be accessed precisely, perhaps I can suggest how you can make it secure.
EDIT: You'll probably want to use public key encryption for this purpose (the RSA algorithm specifically, as it's known to be secure, and is implemented fully in the .NET framework). It's asymmetric, which means that it requires a different key to encrypt (public) and decrypt (private) data. Although I'm still not totally sure how your system works, I suspect you'll just need to restrict access to the private key to just those people who are able to view the database information - you certainly don't want to store it at the same location as the database. Public key can essentially be given to anyone, as it just allows you to encrypt data to be put in the database (assuming write-access to the database is properly restricted). Anyway here are some links to get you started:
Implementing RSA in C#
http://www.dotnetspider.com/resources/692-RSA-Encryption-C.aspx
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.aspx
Hope that helps.
If you're using public key encryption, then you'll want to freely distribute the public key (most likely) and keep access to the private key highly restricted (only on storage media that you know are secure). Either way, it is typical to store keys as base64-encoded strings in XML files. The RSACryptoServiceProvider class has built-in capability to do this, I believe.
Unless your concern is that your data layer is exposed over a web service and you're concerned about possible interception of the data, it sounds like all you need to do is implement encryption on the database itself and not worry about the application.
I had it in mind to use the encryption in basic utility methods mainly for use with a database, but also for configuration data in xml files etc.. and anything else that comes up.
Whatever encryption you use needs keys or pass phrases of one kind or another, I'd like to know where and how you store these strings.
Thanks.