Solved

How do I encrypt (hide) an encryption-key variable without its value being shown in the ildasm (assembly) in C#/.NET deployed on multiple client PCs (WinForm)

Posted on 2006-06-26
23
1,806 Views
Last Modified: 2008-01-09
Hello graye,
Tnx for your comment.
As far as your solution:
first, I have never wrote "How do I safely store encryption keys for my application?".
The original subject is and was always the same!
I have closed the previous question and reworded Alex.P with 500 points (Tnx Alex.P).
Due to your solution I have decided to open a new question (as a follow up) and specifically wrote that the solution must be for deploying the application on multiple client PCs. I need a solution to all casses - encryption on a web server (WebForm) and on multiple client PCs (WinForm).
secone, as far as I know the APAPI is good for working on a single computer (web server) without having to deploy your application to multiple clients using WinForms !!!
Or maybe i should say that the encryption key generated using the DPAPI is special to the machine that the application is running on.
by that NO-ONE cane decrypt a key that is generated and stored on a registry of another machine, but surly you can decryp a key that is generated and stored on your client machine (WinForm).

please let me know if I am right or maybe I got it all wrong ?!?!

Regards
yoffir
0
Comment
Question by:yoffir
  • 7
  • 6
  • 3
  • +4
23 Comments
 
LVL 11

Expert Comment

by:Jase-Coder
ID: 16982898
use the obfuscator program which will scramble your code and prevent people from disassemblign it.
0
 
LVL 11

Expert Comment

by:Jase-Coder
ID: 16982908
should be located here:

C:\Program Files\Microsoft Visual Studio 8\Application\PreEmptive Solutions\Dotfuscator Community Edition

or

C:\Program Files\Microsoft Visual Studio .NET 2003\PreEmptive Solutions\Dotfuscator Community Edition
0
 
LVL 11

Expert Comment

by:Jase-Coder
ID: 16982912
if it is not installed on your system you can get it fromhere: http://www.preemptive.com/products/dotfuscator/index.html
0
 

Author Comment

by:yoffir
ID: 16983243
Tnx,
I am not familiare with this doctrine, but I will chake it.
Still, I would like to get an answer to my original question.

I would appretiate a conclusive and understood answare due to the fact that I am not an expert in .NET and C# and a lot of BUZZ words are not familiar to me.

As I mentioned, I am using Visual Studio 2003 , .Net Framework v1.1 , C#

Tnx.
yoffir
0
 
LVL 2

Expert Comment

by:Naishal
ID: 16983530
I dont think Anyone can so easily decrypt the key which is encrypted by your unexposed algorithm and stored in registry of particular user account on the client side. Of course Algorithm should rock solid to encrypt.

i would readily agree for the concept of storing the key encrypted with your algorithm and stored in the registry of  client's user account on his system.
0
 
LVL 2

Expert Comment

by:Naishal
ID: 16983571
More over i guess Obfuscator may not work to address your concern. It has different purpose. It helps you hide your logic from the disassambling the code but you want your key to be unbreakable and not the logic. Right approach is to first decide where to safely store the key on clients pc given that you dont want to store on server... secondly select good enough encryption algorithm...
0
 
LVL 13

Expert Comment

by:devsolns
ID: 16983590
Where you keep the key depends on where your trust domain is.  For example it may be stored on the machine using the DPAPI under the users logon credentials.  Perhaps its stored remotely and is obtained using an ecrypted channel like SSL and the proper credentials.  The exact scenario depends on a number of things.  Also consider using SecureString where you can when using any keys or passwords because the .NET GC may put a number of copies of that sensitive data in memory for who knows how long.
0
 

Author Comment

by:yoffir
ID: 16983795
people, you really got me exhausted :-)
I just wonted to be able to deploy a .NET Framework 1.1 application on multiple client machine and to use the best way to encrypt the ConnectionString I am using to a DB.

after reading your comments I think it is best that I go back to univercity and study for second degree!!!
Algorithms, SSL, GC - wow

There must be an easiyer way to do this.
I was suggested to use Ngen to create a native image DLL and to put inside this DLL the encryption key I am using in my managed code.
I was also suggested to use DPAPI in order to encrypt my encryption key, but as mentiond in my first comment to "graye" (see above) I understend that DPAPI will not be sutable for deployment other then deployment on my computer. I have the filling that DPAPI is used for web server configuration file such as web.config.

I would like to know if the DPAPI mechanism can be used in my deployed WinForm application and hide my encryption key from being seen using the ildasm or any other decoder?

If it is usable for my deployed .Net Framework v1.1 application - I will appretiate a lot links and information about using the DPAPI mechanism.

At this moment the only solution I have (Tnx to one of the experts) is using the Ngen and create a nativ image for the C# DLL that will contain my encryption key value. This nativ image will be shipped and deployed with the rest of my managed code.

WHAT IS YOUR OPINION?
Please try to send me more in-dept information.

Tnx
yoffir    
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 16987455
who are you trying to stop from attacking your connection string?

A very simple way would just be to house the key on a server (the client requests it to unencrypt its connection string) but this is still attackable by someone who is very knowledgable with a debugger such as windbg ... At some point you hold the key in memory or a register in order to decrypt and at some point that person will be able to see your key.
0
 

Author Comment

by:yoffir
ID: 16987702
More info is needed.

Tnx
yoffir
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 16988325
Please answer the question so I can hope to give you a valid answer. At some point your data will be vulnerable (it is a necessity on a computer system as the program itself needs to access the connection string, in order to do this it must at some point have it in an unencrpyted form).

Are you just trying to protect your key from people viewing with ILDASM? (if so just move the key off to a secure method such as getting it from a webservice or even better using a SSL certificate). If your hope is to prevent the most inquisitive and intelligent hacker from ever getting it, this will simply not happen as at some point you hold the string in memory (which the hacker could view if they have total control over the machine)
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 41

Accepted Solution

by:
graye earned 300 total points
ID: 16988571
Let's talk scenarios....  there's alway a balance between  protection vs inconvience.

I'll concentrate on the client part of the problem, since hiding secrets on a web server is somewhat common place (even for v1.1)

Let's say that I've got a program that I intend to distribute to clients that must have read/write permission to a SQL Server database, but I don't want the users to have any access to the database outside of my own application.  Typically this would be done by using a "secret" database login/password that only the application knows.  If users attempted to connect directly to the database (via their own credentials), they would have no permissions at all.

So now the problem becomes, how do I hide the connection string (which contains the login/password for the database).

Here are several scenarios, in order of complexity and level of protection

1)  Direct encryption -  You'd use a encryption routine inside your application to decypher the connection string.  The cipher text could be stored in the source code, in a config file, in the registry, etc.    Pros:  easy to do.   Cons:  the encryption keys will be visible in the application via disassembly

2)  Indirect encryption -  Similar to the above, but instead of encrypting the connection string itself, you encrypt a set of encryption keys that are later used to decrypt the connection string.  This is an example of one-level of indirection.   Again, the location of the cipher text (now containing just a set of encyrption keys) ca be stored practically anywhere.  Works best when the cipher text is not stored in/near the application (such as the registry).  Pros:  still pretty easy to do.  Cons:  A lot more complicated to break, since the entire source code would be required (still possible via disassembly)

3) Indirect encryption with salt - Similar to the above, but the original encryption keys are "salted" with any combination of the following:  The User's SID, the UUID of the PC, the time of day. The clear-text still contains the encryption keys to the connection string.   Pros:  You could not copy the exe and registry keys to work on breaking them from another PC.  Cons:  Things are beginning to get complicated.  

... and the list goes on, and on, and on....

Let us know if this scenario that I've painted for you is anything like what you're trying to do.
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 16988615
Graye another common scenario is to use integrated authentication and a broker service which runs as this user.

All of these ways are still easily defeated by someone with any clue of what they are doing... as they have full access to the program.

Cheers,

Greg
0
 
LVL 41

Expert Comment

by:graye
ID: 16988677
Greg, true... but I was sensing the frustration of the user with the complexity of the answers.   So I thought I'd "bring it down a notch", and let him pick the balance between complexity and level of protection.   That's the one part that we can't really answer for him.

Personally, I prefer a custom login via a stored procedure using a timecode salt (just like the Ticket Granting Ticket service of Kerberos).  But that's a heck of a lot to get your head around.
0
 

Author Comment

by:yoffir
ID: 16988689
Hello  gregoryyoung,
I must say that this is may second session regarding the encryption issue I am facing.
I am a student of C# .Net Framework v1.1 using visual studio 2003.
At the moment I am facing a huge studential project which involves security conciderations.
As you mentiond, I am trying to hide my encryption key from being seen using decoders such as ILDASM.
I have already build a mechanism that encrypts and decrypts keys/values from the app.config file or any other XML configuration file for that matter.
The ConnectionString is only one parameter that I am encrypting and as i go allong with my project I will probebly encrypt more data in the App.config (at the clients PC's) and in the Web.config in the Web Server.

After a long sessions with some experts in this site I came to a conclusion that the best way is to use a nativ image DLL which holds the encryption key I am using in my algorythm. At first I though to use a nativ C++ or VB6 DLL and link the managed C# code to it. But, again, after reading what the experts suggested I decided to use the Ngen utility and to create a nativ image DLL.

Now I understad from you that there are other ways to do the mission.

I gave you every information possible in order to help me to come up with a final and conclusive solution to my problem.

My project is established on a web server that contains web services and of cource a Web.config file that contains the ConnectionString to the DB.
Also, the project includes WinForm application that connects to the web server and do some other things.
Fore studing matters I would like to have the option to connect from the client application (deployed on several different PC's) to the DB without involving web service.

maybe the deployed WinForm application containse a small DB which deployed allong with the application itself.

In the past there were no problems at all because I could install the ConnectionString in a VB6 DLL and use Win applications and Web applications (ASP) with this DLL.

Now everyone can see the encryption key I am using with my algorithm just by activating the ILDASM utility.

I already know that microsoft has DPAPI algorithm, but this might help me at the web server issue because the encryption key will be generated with "customization" to the web server machine and the only way to "read" it will be on the server itself.
But, again, what about the client side (Win Forms) ?

I would appretiate an in-dept answer due to the fact that I am a novice with the new technology called........Dot.Net.

Regards
yoffir
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 16988782
I hate to be the one to break it to you but putting your information in an unmanaged dll does not make it "secure" in any way shape or form. It will stop someone from running ILDASM on the dll but they can still view the string by using a native debugger/disassembler. This is security through obscurity (as is obfusication/ngen as I can still find out whats going on)

For the server side you are probably ok, if an attacker is able to disassemble your server side dlls you have bigger problems :) The client side is a bit more tricky. The data access that goes through the server should be fairly secure assuming you are using appriate items such as logins and checking priveleges for various items.

"maybe the deployed WinForm application containse a small DB which deployed allong with the application itself."

I would look at using something like SQLite for this purpose (and having a key that was a combination of a local key and a server key to access any sensitive information, butremember even a key gained from a remote source can be compromised as someone with admin rights can do things such as running your app in windbg).

Keep in mind though that any data that you store on that client machine is by its very nature not secure as you have to assume the person has administrator access to that machine. You should therefore only store data which is of low value on that machine (everything else should be accessed through the server (i.e. remoting, webservice, etc)). Perfect example can be seen using MSDE .. You can hide your username/password quite well but I can just change the sa password then view your data as sa. There is no "good" way to work around this as any security you add I can feasably defeat because I am the administrator of the machine (I can get to the processor opcode level which you have to get to at some point, even pieces of hardware are not completely secure when I have admin level access and the proper know how). As such .. only store information that is of limited value on the client machine, store most information in the server where you can control the access to the data.


Since you are doing this for a class I might also go through and do some basic threat modelling http://msdn.microsoft.com/security/securecode/threatmodeling/default.aspx on your application to show that you have been security conscious.

Cheers,

Greg
0
 

Author Comment

by:yoffir
ID: 16988989
graye and Greg, Tnx for the well written comment to my question, especialy the well "bought down a notch" comment of graye - I am positive that graye is a teacher or lecturer ;-)
Lets see if I got all your (you and other experts) adivices and build the pazzle:
1.  A sensitive information should be cept as much as it is pussible in the server side.
2.  The best way to generate an encryption key in the client side is by gaining it from the server itself (e.g.  using remoting or web service or SSL).
3.  A nativ image DLL can be quite easly broken and seen.
4.  The DAPAI encryption algorithm is sutable for the web server encryption but not for the client encryption.

OK until now?

But...what if I am using an application that does not have a server to connect to? maybe I am developing an application that works on isolated environment.
Still, I need a way to connect to a DB that is located on the client's machine or on a remote DB server in the user's LAN network.
In that case I will need a ConnectionString (in a configuration file), I will also need an encryption method, and of cource I will need........an encryption key for that matter.

Well, it seems that we are back at the starting point. isen't it ?

Regards
yoffir
0
 
LVL 37

Assisted Solution

by:gregoryyoung
gregoryyoung earned 150 total points
ID: 16989266
"But...what if I am using an application that does not have a server to connect to? maybe I am developing an application that works on isolated environment.
Still, I need a way to connect to a DB that is located on the client's machine or on a remote DB server in the user's LAN network.
In that case I will need a ConnectionString (in a configuration file), I will also need an encryption method, and of cource I will need........an encryption key for that matter."

1) If you are running a local database such as MSDE (sql server express) the user can gain access to it anyway by changing the admin password so keeping your reduced access user secret doesn't do alot of good (whats the point of stopping the dripping faucet when the ceiling has collapsed from the rain)
2) For 99% of circumstances a simple encryption method will work .. if people are getting past your simple encryption thery will likely get past any other method you throw at them

Remember you are dealing with an attacker that has admin privs on the machine (your app may not even have admin privs). There is no good way to completely shut that attacker down beyond keeping the data in a place that you can control access. As an example remoting would allow you to completely control access to the data, an attacker could only come through your defined contract; since you defined the contract you define the security of the contract.

The fact of the matter is security is a trade off, you need to look at the value of the data in question to figure out how secure it can be. If high levels of security are dictated; the data must be placed into a tightly controlled place.

Cheers,

Greg
0
 

Author Comment

by:yoffir
ID: 16990281
...and so, after your well explained comment, WHAT IS THE TECHNICAL DOCTRIN I SHOULD USE FOR MY PROJECT FOR MY WINFORM APPLICATIONS AND FOR MY WEB FORM APPLICATIONS ?
Theory and academic discussions are a good thing, but still at the end of the day i need to have a solution to start working on !

I would apretiate a lot comments with action items regarding my web application (on my web server machine) and regarding my client application (WinForm).
Please try to answare my original question as written at the subject of this OPEN question.

Thanks in advanced
yoffir
0
 
LVL 30

Assisted Solution

by:Alexandre Simões
Alexandre Simões earned 50 total points
ID: 17000020
Hi...

You got some good answers here already...
I just want to give an idea for a common solution for both Web and Windows environment.

Keep in mind that, when you want to rise a security level, some custom configs must be done, and usually it will be impossible (or dificult) to deploy an app on a customer just running an installation process.

You can use DPAPI and a WebService (WS).
WebServices tho need IIS installed and running.
WebServices can either be deploied on both Windows and web, and if you isolate your DataLayer on the WS, the DPAPI encryption key will never leave the server (even if the "server" is the local machine).

This may be the best solution if you want to have only one way to deal with this for both web and win.


I also told you before, and someone on this thread also mentioned it, about Obfuscating.
There're already some obfuscators that encrypt strings besides only scrambling the code.
I gave you some good links on the previous thread... take a look. I like Xenocode.


At the end...
The security is always expensive, I'm not only talking about money but also performance.
Don't try to make the best security scenario if what you're trying to protec doesn't worth it.

Alex
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 17001780
As I had said, the standard is dependent upon your application. For highly secure data the standard should be to never store it on the client side. For lower value data one can use many mechanisms but one should realize that they are alll velnerable to attack at some level and should therefore be treated as such.

You should always be applying value to your data ... if it takes somebody 2 weeks to break into data that is only good for 30 seconds, who cares ...

As for your basic question of how do I encrypt a connection string while hiding the key .. x509 certificates may be worth looking at http://www.codeproject.com/csharp/cryptography.asp?df=100&forumid=9241&exp=0&select=592187
0
 

Author Comment

by:yoffir
ID: 17003270
Thank you all,
I really need to digest all the given information and try to find a solution to my encryption key problem.
As it seems I will not use the Ngen in order to keep my encryption key in.

Regards
yoffir
0
 
LVL 2

Expert Comment

by:Naishal
ID: 17007078
The best thing available today is...

If your clients are nodes of intranet go for Remoting Or if your clients are nodes of Internet go for WebServices....

Benifits:
1) No need to store connection string at client side
2) You can still implement your business and access logic at server.
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now