2016-06-07 3 views
0

Инструмент: OS-Windows 7 64bit, Visual Studio 2012, 4.5 .NET Framework. Язык: C#.Как защитить закрытый ключ (от Triple DES) в приложении C#?

Я создал одно консольное приложение. В этом приложении я использовал алгоритм шифрования данных (DES-Symmetric Algorithm) для шифрования и дешифрования данных.

Теперь в этом подходе используется закрытый или секретный ключ. Я хочу защитить этот ключ от клиента/Hack. Как я могу его защитить?

На данный момент я сохранил KEY в реестре и прочитал этот ключ из реестра для шифрования и дешифрования, когда это необходимо. Но из реестра любой знающий разработчик, как вы, ребята, может легко прочитать ключ.

Ниже мой DES код алгоритма (я получил этот код из 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); 
     } 
    } 
} 
+0

У вас есть аппаратный модуль безопасности? –

+0

Нет. На самом деле я хочу использовать этот подход для защиты ключа продукта. Я буду шифровать ключ продукта. И для этого мне нужен один закрытый ключ, который я упоминаю в коде. Поэтому я хочу получить секретный ключ, поэтому никто не может получить этот ключ. Потому что, если раз декомпилировать код, Key будет легко виден. – Jaimesh

+1

Итак, вам нужно решение DRM. Нет совершенной безопасности или даже хорошей безопасности. –

ответ

1

Некоторые машины имеют TPM (Trusted Platform Module), а некоторые из них также имеют связку ключей или хранилище ключей, который использует модуль TPM. Маки, как и некоторые машины Windows. Простое шифрование ключа перемещает проблему на защиту ключа шифрования.

Когда вы получаете код, посмотрите, действительно ли он, старый плохой код редко удаляется из Интернета. Код MDN полностью устарел во всех отношениях.

Не используйте DES, он больше не считается защищенным, а 3DES является архаичным и не рекомендуется для новой работы. Вместо этого используйте AES. DES, 3DES и AES - все симметричные ключи.

Не используйте MD5, он больше не считается защищенным, используйте, по крайней мере, SHA256, но для деривации пароля используйте метод, который использует количество соли и итераций, такое как PBKDF2 (функция деривации пароля на основе пароля 2).

Не используйте режим ЕЦБ, он тоже небезопасен, см. ECB mode, прокрутите вниз до Пингвина.

+0

Итак, вы предлагаете мне использовать AES. Это хорошая информация, предоставленная вами. Я принимаю ваше предложение. Но в AES, как я могу применить свой закрытый ключ. Я приведу пример, например [https://msdn.microsoft.com/en-us/library/system.security.cryptography.aes (v = vs.110) .aspx]. Я не хочу динамически создавать ключевые слова. – Jaimesh

+0

AES работает так же, как DES/3DES, за исключением допустимых длин ключей для AES - 128, 192 и 256 бит. Обратите внимание, что DES имеет 56-битную длину ключа и 168-бит 3DES, но это фактически 112 бит из-за возможных ключевых атак. Как AES, так и DES/3DES являются алгоритмами шифрования на основе симметричного ключа. – zaph

+0

Спасибо за ваше предложение. +1 для вашей поддержки. – Jaimesh

1

Вы можете посмотреть на другой ответ мой:

Или вы можете рассмотреть генерации ключа из пароля, который можно использовать для шифрования ключа себя:

В любом случае, вы больше не должны использовать DES, так как он недостаточно безопасен. Triple-DES в порядке, если у вас нет другого выбора. Я рекомендую использовать AES с размером ключа 256 бит, если вам нужен безопасный симметричный алгоритм.


В бывшем Documentation Beta - "stackoverflow.com/documentation", я добавил некоторую дополнительную информацию (.Net Framework -> Шифрование/Cryptography).Поскольку бета-форума, я предоставлю эту информацию здесь:

Создание ключа из пароля/Random ОСВ (в 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 
} 

Этот пример взят из MSDN.

Это демонстрационную консоль и показывает, как создать защищенный ключ на основе пользовательского пароля и как создать произвольную ОСВ на основе криптографического генератора.

Примечание:

  • Встроенные функции PasswordDeriveBytes использует стандартный алгоритм PBKDF1 для генерации ключа из пароля. По умолчанию он использует 100 итераций для генерации ключа, чтобы замедлить атаки грубой силы. Соль, генерируемая случайным образом, еще более укрепляет ключ.

  • Функция CryptDeriveKey преобразует ключ, сгенерированный PasswordDeriveBytes, в ключ, совместимый с указанным алгоритмом шифрования (здесь «TripleDES»), используя указанный алгоритм хеширования (здесь «SHA1»). Ключ в этом примере составляет 192 байта, а вектор инициализации IV берется у поставщика криптотерапии triple-DES

  • Обычно этот механизм используется для защиты более сильного случайного сгенерированного ключа паролем, который шифрует большое количество данные. Вы также можете использовать его для предоставления нескольких паролей разных пользователей для доступа к тем же данным (их защищает другой случайный ключ).

  • К сожалению, CryptDeriveKey настоящее время не поддерживает AES. См here. ПРИМЕЧАНИЕ: В качестве обходного пути, вы можете создать случайный ключ AES для шифрования данных, которые должны быть защищены с AES и хранить ключ AES в TripleDES-контейнер, который использует ключ, сгенерированный CryptDeriveKey. Но это ограничивает безопасность TripleDES, не использует преимущества больших ключей AES и создает зависимость от TripleDES.

+0

Хотя нет оснований не использовать 256-битный ключ AES, 128-битный ключ не менее безопасен. – zaph

+0

@zaph - относительно размера ключа, вы можете подумать об этом: [Обсуждение размера ключа] (https://security.stackexchange.com/questions/14068/why-most-people-use-256-bit-encryption-instead- 128-бит) – Matt

+0

Я знаю, что у меня там есть голосование. В случае квантовых компьютеров, если они станут коммерчески жизнеспособными по цене, 128-битные симметричные ключи будут уменьшены, но реальная катастрофа заключается в том, что асимметричное шифрование полностью нарушено. – zaph

Смежные вопросы