How to Secure Private key(of Triple DES) in C# application?
Asked Answered
S

2

2

Tool : OS-Windows 7 64bit, Visual Studio 2012, 4.5 .NET Framework. Language : C#.

I have created one console application. In this application I have used Data Encryption Algorithm (DES- Symmetric Algorithm) to encrypt and decrypt data.

Now in this approach, Private or secrete key is used. I want to secure this key from client/Hack. How can I secure it?

For now I have stored KEY to the registry, And read that key from registry to encryption and decryption when required. But from registry any knowledgeable developer like you guys can easily read key.

Below is my DES algorithm code(I got this code from MSDN):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace DES_Encrypt_Decrypt
{
    public class Program
    {
        static void Main(string[] args)
        {
            var text = "This is Plain Text";

            var encryptedText = CryptoGraphyExample.EncryptPlainTextToCipherText(text);
            var decryptedText = CryptoGraphyExample.DecryptCipherTextToPlainText(encryptedText);

            Console.WriteLine("Passed Text = " + text);
            Console.WriteLine("EncryptedText = " + encryptedText);
            Console.WriteLine("DecryptedText = " + decryptedText);

            Console.ReadLine();
        }
    }

    public class CryptoGraphyExample
    {
        private const string _securityKey = "MyComplexKey";
        // This is my secret key and I want to secure it to the client machine. 


        public static string EncryptPlainTextToCipherText(string PlainText)
        {                
            byte[] toEncryptedArray = UTF8Encoding.UTF8.GetBytes(PlainText);

            MD5CryptoServiceProvider objMD5CryptoService = new MD5CryptoServiceProvider();

            byte[] securityKeyArray = objMD5CryptoService.ComputeHash(UTF8Encoding.UTF8.GetBytes(_securityKey));

            objMD5CryptoService.Clear();

            var objTripleDESCryptoService = new TripleDESCryptoServiceProvider();

            objTripleDESCryptoService.Key = securityKeyArray;

            objTripleDESCryptoService.Mode = CipherMode.ECB;

            objTripleDESCryptoService.Padding = PaddingMode.PKCS7;

            var objCrytpoTransform = objTripleDESCryptoService.CreateEncryptor();

            byte[] resultArray = objCrytpoTransform.TransformFinalBlock(toEncryptedArray, 0, toEncryptedArray.Length);

            objTripleDESCryptoService.Clear();

            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        public static string DecryptCipherTextToPlainText(string CipherText)
        {
            byte[] toEncryptArray = Convert.FromBase64String(CipherText);

            MD5CryptoServiceProvider objMD5CryptoService = new MD5CryptoServiceProvider();

            byte[] securityKeyArray = objMD5CryptoService.ComputeHash(UTF8Encoding.UTF8.GetBytes(_securityKey));

            objMD5CryptoService.Clear();

            var objTripleDESCryptoService = new TripleDESCryptoServiceProvider();

            objTripleDESCryptoService.Key = securityKeyArray;

            objTripleDESCryptoService.Mode = CipherMode.ECB;

            objTripleDESCryptoService.Padding = PaddingMode.PKCS7;

            var objCrytpoTransform = objTripleDESCryptoService.CreateDecryptor();

            byte[] resultArray = objCrytpoTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            objTripleDESCryptoService.Clear();

            return UTF8Encoding.UTF8.GetString(resultArray);
        }
    }
}
Selfesteem answered 7/6, 2016 at 10:26 Comment(8)
Do you have a hardware security module?Connotative
No. Actually I want to use this approach to Secure product key. I will encrypt Product key. And for this I required one Private key Which I mention in code. So I want to secure private key, so no one can get that key. Because if once code is decompiled, Key will easily visible.Selfesteem
So you want a DRM solution. There is no perfect security or even good security available.Connotative
It is possible to store it some ware in client machine? Or in code with unreadable format? I have refer Obfuscation but it is not strongly secure.Selfesteem
Sure, there are a lot of obfuscation tools around. Use your favorite search engine to find them.Connotative
" While obfuscation can make reading, writing and reverse-engineering a program difficult and time-consuming, it will not necessarily make it impossible.Some anti-virus, such as AVG, will also alert their users when they land on a site with code that is manually obfuscated. The average user may not expect their antivirus software to provide alerts about an otherwise harmless piece of code, especially from trusted corporations, so such a feature may actually serve as a deterrent. " - From Wikipedia.Selfesteem
@zaph : I want to use Symmetric algorithm, in which only private key is required. I want to use this approach in windows form application to protract(Encrypt) product key. and I want that when user run the application, at that time it verify the Product key(which is encrypted). To verify it will decrypt so key is require every time when application will run. So i want to store key in client machine.Selfesteem
AES is a symmetric algorithm. It is virtually impossible to secure data from the device owner, if that s what you want then you need DRM.Doti
N
2

You can have a look at another answer of mine:

Or you can consider generating a key from a password, which you can use to encrypt the key itself:

Either way, you should not use DES any longer as it is not secure enough any more. Triple-DES is okay if you have no other option. I recommend to use AES with a key size of 256 bit if you require a secure symmetric algorithm.


In the former Documentation Beta - "stackoverflow.com/documentation", I had added some additional information (.Net Framework -> Encryption / Cryptography). Since Beta is offline, I will provide this information here:

Create a Key from a Password / Random SALT (in C#)

using System;
using System.Security.Cryptography;
using System.Text;

public class PasswordDerivedBytesExample
{
    public static void Main(String[] args)
    {
        // Get a password from the user.
        Console.WriteLine("Enter a password to produce a key:");

        byte[] pwd = Encoding.Unicode.GetBytes(Console.ReadLine());

        byte[] salt = CreateRandomSalt(7);

        // Create a TripleDESCryptoServiceProvider object.
        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();

        try
        {
            Console.WriteLine("Creating a key with PasswordDeriveBytes...");

            // Create a PasswordDeriveBytes object and then create
            // a TripleDES key from the password and salt.
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, salt);

            // Create the key and set it to the Key property
            // of the TripleDESCryptoServiceProvider object.
            tdes.Key = pdb.CryptDeriveKey("TripleDES", "SHA1", 192, tdes.IV);

            Console.WriteLine("Operation complete.");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            // Clear the buffers
            ClearBytes(pwd);
            ClearBytes(salt);

            // Clear the key.
            tdes.Clear();
        }

        Console.ReadLine();
    }

    #region Helper methods

    /// <summary>
    /// Generates a random salt value of the specified length.
    /// </summary>
    public static byte[] CreateRandomSalt(int length)
    {
        // Create a buffer
        byte[] randBytes;

        if (length >= 1)
        {
            randBytes = new byte[length];
        }
        else
        {
            randBytes = new byte[1];
        }

        // Create a new RNGCryptoServiceProvider.
        RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();

        // Fill the buffer with random bytes.
        rand.GetBytes(randBytes);

        // return the bytes.
        return randBytes;
    }

    /// <summary>
    /// Clear the bytes in a buffer so they can't later be read from memory.
    /// </summary>
    public static void ClearBytes(byte[] buffer)
    {
        // Check arguments.
        if (buffer == null)
        {
            throw new ArgumentNullException("buffer");
        }

        // Set each byte in the buffer to 0.
        for (int x = 0; x < buffer.Length; x++)
        {
            buffer[x] = 0;
        }
    }

    #endregion
}

This example is taken from MSDN.

It is a console demo, and it shows how to create a secure key based on a user-defined password, and how to create a random SALT based on the cryptographic random generator.

Notes:

  • The built-in function PasswordDeriveBytes uses the standard PBKDF1 algorithm to generate a key from the password. Per default, it uses 100 iterations to generate the key to slow down brute force attacks. The SALT generated randomly further strenghens the key.

  • The function CryptDeriveKey converts the key generated by PasswordDeriveBytes into a key compatible with the specified encryption algorithm (here "TripleDES") by using the specified hash algorithm (here "SHA1"). The keysize in this example is 192 bytes, and the initialization vector IV is taken from the triple-DES crypto provider

  • Usually, this mechanism is used to protect a stronger random generated key by a password, which encrypts large amount of data. You can also use it to provide multiple passwords of different users to give access to the same data (being protected by a different random key).

  • Unfortunately, CryptDeriveKey does currently not support AES. See here. NOTE: As a workaround, you can create a random AES key for encryption of the data to be protected with AES and store the AES key in a TripleDES-Container which uses the key generated by CryptDeriveKey. But that limits the security to TripleDES, does not take advantage of the larger keysizes of AES and creates a dependency to TripleDES.

Northumberland answered 25/7, 2017 at 15:26 Comment(4)
While there is no reason not to use an AES 256-bit key a 128-bit key is no less secure.Doti
@Doti - regarding key size, you may consider this: Discussion about key sizeNorthumberland
I am aware of that, I have an up-vote there. In the case of quantum computers, should they become commercially viable price-wise, 128-bit symmetric keys are reduced but the real disaster is that asymmetric encryption is completely broken.Doti
@Doti - DES internally uses a 48 bit subkey. This is why Triple-DES was "invented" before AES came, to have a larger key size. AES was designed from the beginning to deal with larger keys, which is why it is better than DES or Triple-DES. Quantum computers will change everything, new algorithms will be needed in the future.Northumberland
D
1

Some machines have a TPM (Trusted Platform Module) and some also have a keychain or keystore that leverages the TPM. Macs do as do some Windows machines. Just encryption a key moves the problem to securing the encryption key.

When you get code look to see if it is current, old bad code is rarely removed from the Internet. The MDN code is completely out of date in every respect.

Do not use DES, it is no longer consider secure and 3DES is archaic and not recommended for new work. Instead use AES. DES, 3DES and AES are all symmetric keys.

Do not use MD5, it is no longer considered secure, use at least SHA256 but for password derivation use a method that uses a salt and iteration count such as PBKDF2 (Password Based Derivation Function 2).

Do not use ECB mode, it too is insecure, see ECB mode, scroll down to the Penguin.

Doti answered 7/6, 2016 at 11:59 Comment(3)
So, you suggest me to use AES. It's good information provided by you. I accept your suggestion. But in AES, how can I apply my private key. I have refer some example like[msdn.microsoft.com/en-us/library/…. I dont want to create key dynamically.Selfesteem
AES works the same way as DES/3DES except the allowable key lengths for AES are 128, 192 and 256 bits. Note that DES has a 56-bit key length and 3DES 168-bits but that is effectively 112-bits due to possible key attacks. Both AES and DES/3DES are symmetric key block based encryption algorithms.Doti
Thanks for your suggestion. +1 for your support.Selfesteem

© 2022 - 2024 — McMap. All rights reserved.