2009-05-23 3 views
5

Я ищу общий класс шифрования строк в .NET. (Не путать с классом «SecureString».)Общее шифрование строк

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

Public Class SecureString 

     Private key() As Byte 
     Private iv() As Byte 
     Private m_SecureString As String 

     Public ReadOnly Property Encrypted() As String 
      Get 
       Return m_SecureString 
      End Get 
     End Property 

     Public ReadOnly Property Decrypted() As String 
      Get 
       Return Decrypt(m_SecureString) 
      End Get 
     End Property 

     Public Sub New(ByVal StringToSecure As String) 
      If StringToSecure Is Nothing Then StringToSecure = "" 
      m_SecureString = Encrypt(StringToSecure) 
     End Sub 

     Private Function Encrypt(ByVal StringToEncrypt As String) As String 

      Dim result As String = "" 
      Dim bytes() As Byte = Text.Encoding.UTF8.GetBytes(StringToEncrypt) 

      Using provider As New AesCryptoServiceProvider() 

       With provider 
        .Mode = CipherMode.CBC     
        .GenerateKey() 
        .GenerateIV() 
        key = .Key 
        iv = .IV 
       End With 

       Using ms As New IO.MemoryStream 
        Using cs As New CryptoStream(ms, provider.CreateEncryptor(), CryptoStreamMode.Write) 
         cs.Write(bytes, 0, bytes.Length) 
         cs.FlushFinalBlock() 
        End Using 
        result = Convert.ToBase64String(ms.ToArray()) 
       End Using 

      End Using 

      Return result 

     End Function 

     Private Function Decrypt(ByVal StringToDecrypt As String) As String 

      Dim result As String = "" 
      Dim bytes() As Byte = Convert.FromBase64String(StringToDecrypt) 

      Using provider As New AesCryptoServiceProvider() 

       Using ms As New IO.MemoryStream 
        Using cs As New CryptoStream(ms, provider.CreateDecryptor(key, iv), CryptoStreamMode.Write) 
         cs.Write(bytes, 0, bytes.Length) 
         cs.FlushFinalBlock() 
        End Using 
        result = Text.Encoding.UTF8.GetString(ms.ToArray()) 
       End Using 

      End Using 

      Return result 

     End Function 

    End Class 
+0

Эмм, вам необходимо пройти IV для дешифрования. – Migol

+0

@Migol - Не могли бы вы прояснить свой комментарий? – user111370

+0

IV может быть отправлен через opentext и содержит некоторые данные, кроме ключа, для расшифровки вашей строки. – Migol

ответ

4

AES алгоритм симметричного шифрования, как правило, путь для общего шифрования строк. Тем не менее, я боюсь, что .NET BCL не упрощает для вас дальнейшее предоставление основных классов и функций шифрования/дешифрования.

Вы можете найти хороший пример того, как использовать криптографические классы специально для строкового шифрования на this page. Это, кажется, очень полно и хорошо прокомментировано - вы даже можете обнаружить, что можете использовать его без каких-либо дополнительных изменений. Примечание: Rijndael - тот же алгоритм, что и AES. (. С технической точки зрения бывший относится к реальному имени алгоритма, а последний Advanced Encryption Standard)

+0

@Noldorin - Спасибо за ссылку! Есть ли какая-либо общая функция, которую я могу передать строкой любой кодировки и использовать любого из поставщиков криптографических услуг? – user111370

+0

@cryptospin: проблем нет. Просто понял, что я немного неправильно понял ваш первоначальный вопрос. Во всяком случае, я только что обновил сообщение. Конечно, в .NET Framework определенно нет вспомогательного класса/методов для этого. Боюсь, хотя код на связанной странице должен предоставить вам хорошую отправную точку. Хорошим способом для этого может быть использование методов расширения здесь. – Noldorin

3

Если вы пытаетесь достичь той же цели как SecureString .NET, тогда ваш пример действительно не решает проблему. (Я мог бы неправильно понять ваши цели, и в этом случае я приношу свои извинения.)

Идея SecureString .NET заключается в том, что она хранит строковые данные, зашифрованные в неконтролируемом блоке памяти, неизменяема после создания и не может читайте в .NET с использованием обычной строковой переменной. Это защищает строку от всех, кто пытается исследовать ваше пространство памяти (например, вредоносное ПО, червь, троянец, что угодно) и должен быть явно очищен вами. Причины этого связаны с тем, как .NET обрабатывает строки, а также тот факт, что данные в памяти очищаются только по прихоти GC.

Даже если ваш класс SecureString шифрует строку в приватную переменную, исходная строка, которая была передана, по-прежнему небезопасна. Он может также зависнуть некоторое время до того, как GC соберет его, или, если эта строка была интернирована, он будет жить в течение всего процесса, в котором он находится. Интернированные строки хранятся в таблице, что также облегчает их поиск.

С другой стороны ... если вы расшифруете свою SecureString, вы получите новую строковую переменную, которая может работать в тех же проблемах, что и входная строка ... она очищается только тогда, когда GC решает. .. и он также может закончиться интернированным и жить в течение всего процесса.

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

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

Его определенно сложная проблема, и только на самом деле обеспечивает безопасность в том случае, если пространство вашего приложения было скомпрометировано каким-то вредоносным программным обеспечением.

+0

Спасибо, что нашли время для публикации. Если вы читаете OP, я явно указываю «(Не путать с классом« SecureString ».)« – user111370

+0

«Это защищает строку от любого, кто пытается исследовать ваше пространство памяти», это не так и не делается. Если вы можете прочитать память процесса, вы можете почти наверняка ввести собственный код, и в этот момент извлечение открытого текста за «SecureString's» тривиально. Он только держит строку из аварийных дампов, файла подкачки и т. Д. – CodesInChaos

+0

@CodesInChaos: текст не является простым, он зашифрован. Если «SecureString» просто хранит простой текст в неуправляемой куче, я бы согласился, он, вероятно, сохранил бы его только из аварийных дампов, swap-файла и т. Д. Учитывая, что строка зашифрована, она защищает всех, кто может быть зондирующим ваша память сразу получает свою ценность. Разумеется, грубая сила или, возможно, известные атаки (если они есть для вашего протокола безопасности) могут по-прежнему разрушать шифрование, но это технически имеет дело с каждым механизмом безопасности. Поэтому я поддерживаю свое заявление. – jrista

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