why we hide away the "lock" and give away a "key"?

My application uses a text file that i would like to encrypt. I know .NET encryption classes and routines, but i am not sure how i am going to secure a "Key", that generates the cipher Most security experts suggest to keep "Key" in more secure location,I wonder where is it What exactly is secure location where is it we hide the "lock" and give away a "key"



Answer this question

why we hide away the "lock" and give away a "key"?

  • tedh

    The topic of encryption and keys is too complex to discuss fully in a topic post but I'll give a brief synopsis. Caveat however is that I'm not a security expert by any stretch so you should rely on the documentation as well. Firstly there are different types of encryption: one-way hash, symmetric, asymmetric. You should determine the best one to use based on your situation.

    One-way hashes are good for securing things that you don't need to get back. This sounds sort of bizarre but if you think about the canonical example it makes sense. Windows stores (at least use to) user passwords as an encrypted one-way hash. The reason is that Windows doesn't really care what your password is nor does it ever provide you the option of getting it back. Instead Windows just wants to verify who you are so provided the password you give it hashes to the one it stores then you must be right. This is good for storing passwords and verifying identity but not much else.

    Symmetric (SE) and asymmetric (AE) encryption involves the sending and exchanging of public and private keys. SE is good for large blocks of data while AE is good for small blocks of data. SE uses a public key and an initialization vector to encrypt data. To decrypt the data you need the same values. Therefore you have to store both the key and the IV. AE uses a public and private key to encrypt. To decrypt you need the public key. The private key must be securely stored.

    Another option when you are dealing with a specific machine or user is DPAPI. DPAPI (available in managed code as of v2.0) encrypts based on the current machine or user and requires no storage of any key and yet provides the same security. The downside is that anybody on the machine (or the user) can see the data if they chose (by decrypting it). Oftentimes several layers of encryption are used such as DPAPI along with salting (mixing additional values into the data to make it more random).

    You'll need to store your key(s) in a secure place in the registry or on the file system. Encrypting the key itself or two-way hashing is also a good idea. You can find a good article on MSDN about generating keys: Generating Keys for Encryption and Decryption. Another article about securing keys can be found with How to: Asymmetric Keys in a Key Container.

    Michael Taylor - 2/7/06


  • Tony Virnoche

    From what I understand, and I could be wrong here, the key container is created as a secured resource such that only the SYSTEM and CREATOR have access to the container. Therefore 2 different apps can access the key container only if they both know the name of the container and are run under the context of the same user. I tried a simple test where I created the container under one account and attempted to read encrypted data from another account and it failed yet I could read and write from the same account just fine.

    However since it is easy to get the key container name and someone could easily set up a program to run under your account (such as a service or ActiveX control) using a key container to encrypt data doesn't seem to be that secure unto itself. It seems to be more useful for sharing keys across applications. I'd still combine this with an additional encryption layer of some sort.

    Michael Taylor - 2/9/06


  • nvierros

    Hello,

    I read the article Store Asymmetric Keys in a Key Container from MSDN. However I have few queries.

    1. Where is the key container stored. Are the keys stored in a machine registry of some sort

    2. Is the key container available over time (say during an entire session in a web application)

    3. Is the named key container available across application boundaries

    If someone has any knowledge about this please enlighten me. Thanks in advance.

    Amiya.


  • Mike Vernal

    I read the article on MSDN titled, "Store Asymmetric Keys in a Key Container" interseting. And this is exactly what i am searching on. But there is one last issue, if this is code my applicaion will be using to add the key

    Dim cp As New CspParameters()
    cp.KeyContainerName = "MyKeyContainer"

    ' Create a new instance of RSACryptoServiceProvider that accesses
    ' the key container MyKeyContainerName.
    Dim rsa As New RSACryptoServiceProvider(cp)

    ' Display the key information to the console.
    Console.WriteLine("Key added to container: {0}", rsa.ToXmlString(True))

    and this is the code to read the key

    Dim cp As New CspParameters()
    cp.KeyContainerName = "MyKeyContainer"

    ' Create a new instance of RSACryptoServiceProvider that accesses
    ' the key container MyKeyContainerName.
    Dim rsa As New RSACryptoServiceProvider(cp)

    ' Display the key information to the console.
    Console.WriteLine("Key retrieved from container : {0}", rsa.ToXmlString(True))

    Say my application is myapp.exe and do all above twicks, what if same code is written by theaf.exe to read the key, again we opened the key "MyKeyContainer"

    Shawn Farkas - MS wrote:

    Michael is dead-on with his response. Security people often refer to encryption as replacing a large secret (the data you encrypt) with a small secret (the key you encrypt with). The problem is, as you've noticed, you're still left with a secret!

    Key management can be one of the more difficult aspects of cryptography -- you can use the best encryption algorithm around, but if your key leaks it was useless. That's why we strongly recommend using DPAPI to let Windows take care of the hard work for you. Take a look at the ProtectedData class that ships with version 2.0 of the .NET Framework ... it should make your life a lot easier.

    -Shawn


  • HelloWorld .Net

    I think this is on topic since I'm using the ProtectedData class (DPAPI). I realy thought I found the holy grail until I sent the protected data to another machine. Argh!

    I have a Windows Service running as SYSTEM. My client app Protects some data and then I send the byte[ ] across a secure remoting channel with impersonation. I verified that I am impersonated in the service and, on the same machine, I can Unprotect the data fine. Across machines I get a CryptographicException: "Key not valid for use in specified state".

    Should this work If my account is being impersonated in a process, what difference does it make if the two processes are on different machines.

    If this is a bug, I have code to repro.

    Thanks,

    Dave



  • Aperionvi

    Michael is dead-on with his response. Security people often refer to encryption as replacing a large secret (the data you encrypt) with a small secret (the key you encrypt with). The problem is, as you've noticed, you're still left with a secret!

    Key management can be one of the more difficult aspects of cryptography -- you can use the best encryption algorithm around, but if your key leaks it was useless. That's why we strongly recommend using DPAPI to let Windows take care of the hard work for you. Take a look at the ProtectedData class that ships with version 2.0 of the .NET Framework ... it should make your life a lot easier.

    -Shawn



  • dimadd

    The input in this post has been extremely helpful so thank you for those that have contributed. From what I have read the Private Key for a X509Certificate2 object is protected using the same methods that the DPAPI and ProtectedData class implement. I need to be able to read the contents of a Private Key and encode it for use with a third party device.

    Is it possible, using the ProtectedData class to get the contents of the Private Key for a Certificate I know that the Private Key is stored as a file in the \Application Data\Microsoft\Crypto\RSA\ directory structure. Are these files encrypted using DPAPI or the ProtectedData class If so is it possible to decrypt the contents Do you have to provide the OptionalEntropy value to decrypt it Are there any examples of how to get the contents of a PrivateKey If there is another (or better) way to get the contents of the Private Key I would appreciate any pointers. Thanks very much!

  • jayakumar

    DPAPI by default only permits the same user on the same machine to decrypt data. To work around this issue you must use a network user that has a roaming profile. In this case the necessary keys (stored in the user's profile) will be transferred to the machine they log into and therefore accessible through DPAPI. At least that is what I understand from the documentation.

    If you want to share data across multiple machines then you'll probably need to switch to ASE with a shared key. This is how ASP.NET is normally configured when running in a web farm environment. The key used to encrypt the data stored in the page (view state, session data, authentication cookies, etc.) is actually stored in the configuration file (machineKey). This key must be the same across all web servers hosting the app. If this isn't done then the user may connect to one server in the farm but then fail to post back to one of the other servers because the data will fail validation.

    Michael Taylor - 2/17/06


  • Kenny Wolf

    I read the article on MSDN titled, "Store Asymmetric Keys in a Key Container" interseting. And this is exactly what i am searching on. But there is one last issue, if this is code my applicaion will be using to add the key

    Dim cp As New CspParameters()
    cp.KeyContainerName = "MyKeyContainer"

    ' Create a new instance of RSACryptoServiceProvider that accesses
    ' the key container MyKeyContainerName.
    Dim rsa As New RSACryptoServiceProvider(cp)

    ' Display the key information to the console.
    Console.WriteLine("Key added to container: {0}", rsa.ToXmlString(True))

    and this is the code to read the key

    Dim cp As New CspParameters()
    cp.KeyContainerName = "MyKeyContainer"

    ' Create a new instance of RSACryptoServiceProvider that accesses
    ' the key container MyKeyContainerName.
    Dim rsa As New RSACryptoServiceProvider(cp)

    ' Display the key information to the console.
    Console.WriteLine("Key retrieved from container : {0}", rsa.ToXmlString(True))

    Say my application is myapp.exe and do all above twicks, what if same code is written by theaf.exe to read the key, again we opened the key "MyKeyContainer"

    TaylorMichaelL wrote:

    The topic of encryption and keys is too complex to discuss fully in a topic post but I'll give a brief synopsis. Caveat however is that I'm not a security expert by any stretch so you should rely on the documentation as well. Firstly there are different types of encryption: one-way hash, symmetric, asymmetric. You should determine the best one to use based on your situation.

    One-way hashes are good for securing things that you don't need to get back. This sounds sort of bizarre but if you think about the canonical example it makes sense. Windows stores (at least use to) user passwords as an encrypted one-way hash. The reason is that Windows doesn't really care what your password is nor does it ever provide you the option of getting it back. Instead Windows just wants to verify who you are so provided the password you give it hashes to the one it stores then you must be right. This is good for storing passwords and verifying identity but not much else.

    Symmetric (SE) and asymmetric (AE) encryption involves the sending and exchanging of public and private keys. SE is good for large blocks of data while AE is good for small blocks of data. SE uses a public key and an initialization vector to encrypt data. To decrypt the data you need the same values. Therefore you have to store both the key and the IV. AE uses a public and private key to encrypt. To decrypt you need the public key. The private key must be securely stored.

    Another option when you are dealing with a specific machine or user is DPAPI. DPAPI (available in managed code as of v2.0) encrypts based on the current machine or user and requires no storage of any key and yet provides the same security. The downside is that anybody on the machine (or the user) can see the data if they chose (by decrypting it). Oftentimes several layers of encryption are used such as DPAPI along with salting (mixing additional values into the data to make it more random).

    You'll need to store your key(s) in a secure place in the registry or on the file system. Encrypting the key itself or two-way hashing is also a good idea. You can find a good article on MSDN about generating keys: Generating Keys for Encryption and Decryption. Another article about securing keys can be found with How to: Asymmetric Keys in a Key Container.

    Michael Taylor - 2/7/06


  • why we hide away the "lock" and give away a "key"?