Nano Hash - криптовалюты, майнинг, программирование

Шифрование и дешифрование сериализованного объекта

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

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

Я пытался следовать документации по классу CryptoStream, но по какой-то причине это не работает. Я думаю, что шифрование может работать, но файл намного меньше, чем незашифрованный эквивалент .ser, поэтому я не знаю. Расшифровка генерирует «Попытка десериализации пустого потока». ошибка, которая довольно понятна, но я не могу понять, как ее исправить.

Резервное копирование и восстановление работают нормально без шифрования.

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

Зашифровать резервную копию:

Private Sub encryptBackup()
    Dim key As Byte()
    Dim IV As Byte() = New Byte() {}

    Using MD5 As New MD5CryptoServiceProvider
        Dim tmp = System.Text.Encoding.UTF8.GetBytes(InputBox("Please insert password:", "Password Input") & "This is most definitely not an obtuse amount of salt")
        key = MD5.ComputeHash(tmp)
        IV = MD5.ComputeHash(key)
    End Using
    Using cryptoRijndael = Rijndael.Create()

        Dim cryptoCryptor As ICryptoTransform = cryptoRijndael.CreateEncryptor(key, IV)
        Using fStream As New FileStream(fldBackupJobs & "\Backup Files\" & Strings.Replace(Strings.Replace(Now, ":", "_"), "/", ".") & ".bin", FileMode.OpenOrCreate), cStream As New CryptoStream(fStream, cryptoCryptor, CryptoStreamMode.Write)
            Dim Formatter As New BinaryFormatter
            Formatter.Serialize(cStream, photoJobs)
            MsgBox("Written to file")
        End Using
    End Using
End Sub

Расшифровать резервную копию:

Private Sub decryptBackup(pathsStr As String)
    photoJobs = Nothing
    Dim key As Byte()
    Dim IV As Byte() = New Byte() {}
    Using MD5 As New MD5CryptoServiceProvider
        Dim tmp = System.Text.Encoding.UTF8.GetBytes(InputBox("Please insert password:", "Password Input") & "This is most definitely not an obtuse amount of salt")
        key = MD5.ComputeHash(tmp)
        IV = MD5.ComputeHash(key)
    End Using
    Using cryptoRijndael = Rijndael.Create()
        Dim cryptoCryptor As ICryptoTransform = cryptoRijndael.CreateEncryptor(key, IV)
        pathstr = OpenFileDialog.FileName
        Using fStream As New FileStream(pathstr, FileMode.Open), cStream As New CryptoStream(fStream, cryptoCryptor, CryptoStreamMode.Read)
            Dim Formatter As New BinaryFormatter
            photoJobs = CType(Formatter.Deserialize(cStream), Dictionary(Of String, PhotoJob))
            MsgBox("Backup Restored")
        End Using
    End Using
End Sub

И ссылка GIT: https://github.com/hughesjs/Photo-Gift-Manager

Заранее спасибо!!


Ответы:


1

Первая часть кода заставляет меня задуматься, потому что (за пределами GoTo) похоже, что метод шифрования зависит от расширения файла. Поскольку пользователь может изменить это через Проводник, это очень хрупко. И не позволяйте пользователю выбирать: если нужно зашифровать, сделайте это; если нет, то не надо. Конечно, метод шифрования не должен зависеть от них (мы получаем большие деньги, чтобы принимать эти решения за них).

Шифрование с использованием BindingList(of Animal), которое мне оказалось под рукой:

Dim key As Byte()
Dim iv As Byte() = New Byte() {}

' see notes below
Using MD5 As New MD5CryptoServiceProvider
    ' UTF8 not unicode; convert password to Byte()
    Dim tmp = Encoding.UTF8.GetBytes(password & "$*^!#" & password)
    ' hash the PW to get the crypto Key
    key = MD5.ComputeHash(tmp)
    ' hash the Key to get the IV
    iv = MD5.ComputeHash(key)
End Using
    
Using rijAlg = Rijndael.Create()
      
    ' Create cryptor using the Key and IV
    Dim cryptor As ICryptoTransform = rijAlg.CreateEncryptor(key, IV)

    ' Open a filestream for the output file, wrap it with
    ' a CryptoStream created with the cryptor in WRITE (output) mode
    Using fs As New FileStream("C:\Temp\crypto.bin", FileMode.OpenOrCreate),
       cs As New CryptoStream(fs, cryptor, CryptoStreamMode.Write)

        ' serialize collection to CryptoStream (to disk)
        Dim bf As New BinaryFormatter
        bf.Serialize(cs, mcol)
    End Using

End Using

Для расшифровки используйте тот же ключ и IV:

mcol = Nothing

' the comments above pertain, just in reverse
Using rijAlg = Rijndael.Create()
    Dim cryptor As ICryptoTransform = rijAlg.CreateDecryptor(key, iv)
    Using fs As New FileStream("C:\Temp\crypto.bin", FileMode.Open),
       cs As New CryptoStream(fs, cryptor, CryptoStreamMode.Read)

        Dim bf As New BinaryFormatter
        ' Convert object to type
        mcol = CType(bf.Deserialize(cs), BindingList(Of Animal))
    End Using
End Using

' test:
For Each a As Animal In mcol
    Console.WriteLine(a.Name)
Next

Все мои животные пережили поездку:

Ровер
Гизмо
Зигги

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

Кроме того, эта строка показывает, что вы не используете Option Strict:

photoJobs = formatter.Deserialize(memStreamSerial)

Deserialize возвращает объект, а photoJobs представляет собой своего рода коллекцию IIRC из прошлых сообщений. Обратите внимание, что мой код использует CType для преобразования в BindingList(Of Animal).

Используйте Option Strict для чего-то более сложного, чем «Hello, World». Всегда.


Крипто примечания / предостережения

Получение (хеширование) IV из пароля — плохая идея: это должны быть независимые фрагменты данных. IV должен быть уникальным для каждого фрагмента данных (чего не будет при повторном использовании PW) и уникальным. Я добавил некоторый произвольный текст в PW, чтобы хэш MD5 не был напрямую получен из PW, но он все еще неоптимален.

Во-вторых, MD5 устарел.

Чтобы создать случайный IV

Private Const MinSize = 7
Public Shared Function GetRandomBytes(size As Integer) As Byte()
    ' dont allow less than a sensible min
    Dim data(If(size < MinSize, MinSize, size)) As Byte

    Using rng As New RNGCryptoServiceProvider
        ' fill the array 
        rng.GetNonZeroBytes(data)
    End Using
    Return data

End Function

Поместите это в библиотеку криптоинструментов, потому что вы будете использовать ее для IV, а также соль для хэшей. Пример:

 myIV = CryptoUtils.GetRandomBytes(15)

Если IV каждый раз уникален, хитрость заключается в том, как сохранить его, чтобы одни и те же значения можно было использовать при расшифровке. IV не обязательно должен быть секретным, поэтому его можно сохранить в FileStream до того, как вы передадите его конструктору CryptoStream. Метод Decrypt делает обратное.

Их тоже можно преобразовать в методы, чтобы каждый раз использовался один и тот же процесс.


Наконец, ваши вопросы получат лучший отклик, если они будут более лаконичными. Ошибка явно указывает на проблему с криптографией, поэтому первые 2 блока являются более или менее шумными.

13.04.2015
  • Ааа, хорошо, спасибо за вашу помощь, я пытался разобраться в официальной документации, и это явно не сработало... Шифрование, кажется, теперь работает нормально, просто я получаю сообщение об ошибке при расшифровке, говорящее, что это не вводя действительный двоичный поток в двоичный форматтер? Я пытался в течение последнего часа или около того, чтобы исправить это, но ничего из того, что я делаю, похоже, не работает. 14.04.2015
  • Мне нужно увидеть код, чтобы понять, в чем заключается новая, текущая проблема. Вы можете добавить его к своему исходному сообщению... покажите оба метода Encrypt и Decrypt, поскольку последний потерпит неудачу, если вы оба сделаете первый. 14.04.2015
  • Я добавил пошаговые комментарии к моему методу Encrypt — сравните то, что я сделал, с тем, что у вас есть. Нет смысла создавать memstream, когда вы можете сериализовать прямо на диск через CryptoStream. Для расшифровки вам нужно сделать обратное - вы не открываете файл, который я вижу, поэтому BinaryFormatter пытается работать с пустым потоком. в основном, ваш текущий код совсем не похож на мой. Криптовалюта требует дополнительной точности, один ложный байт и ничего не работает. 14.04.2015
  • Итак, если я просмотрел мой код, и, кроме разных имен переменных и дополнительного бита для пересчета ключа и IV в подразделе расшифровки, я не вижу ничего другого, и теперь я подтверждаю опцию strict... Извините, что я такая боль, я просто серьезно сбит с толку. Он не работает на пустом потоке, ему передается путь к файлу, я бы не хотел использовать временную папку, и ошибка показывает каскад шифрования как неправильно отформатированный поток. 14.04.2015
  • Гораздо лучше и чище (сейчас - может быть, я не видел окончательный вариант?). Там еще есть плохие идеи, но проблема в каком-то неаккуратном копипасте. В вашем DeCryptor измените его на: cryptoRijndael.CreateDecryptor(key, IV) он создает ENcrpytor (см. примечание выше о точности). Лучший способ создания/управления именами файлов представлен в System.IO.Path измельчении строк на биты, и бобы могут очень быстро выйти из строя. 14.04.2015
  • Вы, сэр, ВЕЛИКИЙ человек, большое спасибо, как я уже сказал, это был мой первый набег на шифрование, поэтому я очень ценю помощь. 14.04.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

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