-1

Я был просить, чтобы сделать задачу в проект, который включает в себя шифрование под управлением Windows 8.Создание/дешифрования паролей с солью/IV

Сценарий что-то вроде этого:

Я получаю byte[] с сервера первые 16 байтов - это IV, а следующие 128 - Salt, а остальные - сами файлы.

Затем пользователь предоставляет пароль, а вместе с ним и солью я должен создать ключ PKCS5 с 40 итерациями, а ключ должен иметь длину 32 байта.

Прямо сейчас я разделил в 3-м запросе, но я не знаю, как это делается в Windows C#.

ответ

1

Я проделал определенную работу с шифрованием/расшифровкой, но позвольте мне предоставить вам ресурс, который я использовал для шифрования AES 256 бит. Надеюсь, это даст вам представление о том, как переключить его на PKCS5, но все остальное, на что я уверен, то же самое. Это немного длинно, но дайте мне знать, если это относится к вашей ситуации. Мне любопытно, насколько сильно это было бы для PKCS5 вместо AES256.

Редактировать: поскольку код, который они размещали, не был ясен на итерациях, итерации контролируются линией var key = Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); с использованием 1000 итераций.

http://www.codeproject.com/Articles/769741/Csharp-AES-bits-Encryption-Library-with-Salt

Ядро шифрования кода

using System.Security.Cryptography; 
using System.IO; 

Шифрование

public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes) 
{ 
    byte[] encryptedBytes = null; 

    // Set your salt here, change it to meet your flavor: 
    // The salt bytes must be at least 8 bytes. 
    byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 

    using (MemoryStream ms = new MemoryStream()) 
    { 
     using (RijndaelManaged AES = new RijndaelManaged()) 
     { 
      AES.KeySize = 256; 
      AES.BlockSize = 128; 

      var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); 
      AES.Key = key.GetBytes(AES.KeySize/8); 
      AES.IV = key.GetBytes(AES.BlockSize/8); 

      AES.Mode = CipherMode.CBC; 

      using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write)) 
      { 
       cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length); 
       cs.Close(); 
      } 
      encryptedBytes = ms.ToArray(); 
     } 
    } 

    return encryptedBytes; 
} 

дешифрование

public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes) 
{ 
    byte[] decryptedBytes = null; 

    // Set your salt here, change it to meet your flavor: 
    // The salt bytes must be at least 8 bytes. 
    byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 

    using (MemoryStream ms = new MemoryStream()) 
    { 
     using (RijndaelManaged AES = new RijndaelManaged()) 
     { 
      AES.KeySize = 256; 
      AES.BlockSize = 128; 

      var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); 
      AES.Key = key.GetBytes(AES.KeySize/8); 
      AES.IV = key.GetBytes(AES.BlockSize/8); 

      AES.Mode = CipherMode.CBC; 

      using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write)) 
      { 
       cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length); 
       cs.Close(); 
      } 
      decryptedBytes = ms.ToArray(); 
     } 
    } 

    return decryptedBytes; 
} 

Получение рандомизированные Шифрование R esult with Salt

Если мы шифруем один и тот же контекст (т. строка «Hello World») в 10 раз, зашифрованные результаты будут одинаковыми. Что делать, если мы хотим, чтобы результаты отличались от каждого зашифрованного?

Что я делаю, это добавить случайные байты соли перед исходными байтами перед шифрованием и удалить их после дешифрования.

Пример добавляющим рандомизированного соли Перед шифрованного строковое

public string Encrypt(string text, string pwd) 
{ 
    byte[] originalBytes = Encoding.UTF8.GetBytes(text); 
    byte[] encryptedBytes = null; 
    byte[] passwordBytes = Encoding.UTF8.GetBytes(pwd); 

    // Hash the password with SHA256 
    passwordBytes = SHA256.Create().ComputeHash(passwordBytes); 

    // Generating salt bytes 
    byte[] saltBytes = GetRandomBytes(); 

    // Appending salt bytes to original bytes 
    byte[] bytesToBeEncrypted = new byte[saltBytes.Length + originalBytes.Length]; 
    for (int i = 0; i < saltBytes.Length; i++) 
    { 
     bytesToBeEncrypted[i] = saltBytes[i]; 
    } 
    for (int i = 0; i < originalBytes.Length; i++) 
    { 
     bytesToBeEncrypted[i + saltBytes.Length] = originalBytes[i]; 
    } 

    encryptedBytes = AES_Encrypt(bytesToBeEncrypted, passwordBytes); 

    return Convert.ToBase64String(encryptedBytes); 
} 

Примера из Удаления соли после Decryption

public string Decrypt(string decryptedText, string pwd) 
{ 
    byte[] bytesToBeDecrypted = Convert.FromBase64String(decryptedText); 
    byte[] passwordBytes = Encoding.UTF8.GetBytes(pwd); 

    // Hash the password with SHA256 
    passwordBytes = SHA256.Create().ComputeHash(passwordBytes); 

    byte[] decryptedBytes = AES_Decrypt(bytesToBeDecrypted, passwordBytes); 

    // Getting the size of salt 
    int _saltSize = 4; 

    // Removing salt bytes, retrieving original bytes 
    byte[] originalBytes = new byte[decryptedBytes.Length - _saltSize]; 
    for (int i = _saltSize; i < decryptedBytes.Length; i++) 
    { 
     originalBytes[i - _saltSize] = decryptedBytes[i]; 
    } 

    return Encoding.UTF8.GetString(originalBytes); 
} 

кода для получения случайных байт

public byte[] GetRandomBytes() 
{ 
    int _saltSize = 4; 
    byte[] ba = new byte[_saltSize]; 
    RNGCryptoServiceProvider.Create().GetBytes(ba); 
    return ba; 
} 
+1

Прочитайте последнюю строчку, которую он разместил «Прямо сейчас я разделил байт [] в 3-м классе, но я не знаю, как это делается в Windows C#.», Который говорит мне, что он разделяет байты на 3 штуки, но он не знает, как их зашифровать/расшифровать, используя IV, соль и файл. Также я не копировал всю статью, а только части, относящиеся к его вопросу. Когда я отправил сообщение без цитирования частей статьи, которые имеют отношение к делу, мне говорят, чтобы процитировать его, если что-то случится с ним позже. – dakre18

+0

Я вижу. Это все еще не нормально. Помимо проблем с форматированием в вашем ответе, он не согласен ответить на плохие вопросы. OP хочет, чтобы кто-то доставлял им довольно много кода, не показывая, что они пытались, и что не сработало. Переполнение стека не должно быть услугой кодирования. –

+0

Правда, и разве это не технически лучше подходит в одном из обменов стека безопасности или программирования? Это может быть полезно для ОП. – dakre18

1

Шаг 1: Split входящие данные в IV, соль и cyphertext. Вы говорите, что сделали это.

Шаг 2: Передайте прилагаемый пароль и соль с шага 1 в качестве входных данных для метода генерации ключей PKCS5 с использованием 40 итераций. В вашей крипто-библиотеке должен быть класс PKCS5. Результатом этого шага будет ключ.

Шаг 3: Используйте ключ с шага 2 и IV с шага 1 для дешифрования cyphertext с шага 1. Используйте указанный алгоритм дешифрования, возможно AES, в указанном режиме. Поскольку предоставляется IV, возможно, что режим CBC предназначен, поэтому вам, вероятно, понадобится использовать режим AES-CBC из вашей библиотеки cypher. Проверьте спецификацию проблемы, чтобы подтвердить как алгоритм, так и режим cypher - я только угадываю здесь.

Если у вас возникли проблемы с любыми этими шагами, спросите здесь еще раз, показывая свой код и объясняя ошибки, которые вы получаете.

+0

Что такое библиотека криптографии, которую я должен использовать? – Ric

+1

Начните с библиотеки, встроенной в C#, если она есть. В противном случае поговорите со своим боссом/инструктором и посмотрите, что является стандартом для вашей рабочей/учебной среды. Если нет стандартного набора, попробуйте [Bouncy Castle] (http://www.bouncycastle.org/csharp/). – rossum

+0

Мне удалось сделать то, что я хотел, используя https://www.nuget.org/packages/pclcrypto :) – Ric

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