Шифрование / дешифрование XML в отдельных файлах

#xml #vb.net #cryptography #rijndael

#xml #vb.net #криптография #rijndael

Вопрос:

Мне нужно зашифровать XML-файл, отправить его в другое место и расшифровать его там. Как вы можете видеть из приведенных ниже кодов, я использую тот же ключ, но он не будет работать (на данный момент я просто использую два локальных файла).

Ошибка, которую я получаю, заключается в следующем:

Заполнение недопустимо и не может быть удалено.

в этой строке в Decrypt.aspx: Затемнить xReader как XmlTextReader

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

Encrypt.aspx

  Dim rijnAlg As RijndaelManaged
 rijnAlg = RijndaelManaged.Create()

 rijnAlg.Key = {118, 123, 23, 17, 161, 152, 35, 68, 126, 213, 16, 115, 68, 217, 58, 108, 56, 218, 5, 78, 28, 128, 113, 208, 61, 56, 10, 87, 187, 162, 233, 38}
 rijnAlg.IV = {33, 241, 14, 16, 103, 18, 14, 248, 4, 54, 18, 5, 60, 76, 16, 191}
 Dim encryptor As ICryptoTransform
 encryptor = rijnAlg.CreateEncryptor(rijnAlg.Key, rijnAlg.IV)

 Dim wStream As FileStream
 wStream = File.Open("C:test.xml", FileMode.Create)

 Dim cStream As CryptoStream
 cStream = New CryptoStream(wStream, encryptor, CryptoStreamMode.Write)

 Dim sWriter As StreamWriter
 sWriter = New StreamWriter(cStream)

 XMLDoc.Save(sWriter)

 'Clear memory'
 wStream.Flush()
 wStream.Close()
  

Расшифровать.aspx

  Dim rijnAlg As RijndaelManaged
 rijnAlg = RijndaelManaged.Create()

 rijnAlg.Key = {118, 123, 23, 17, 161, 152, 35, 68, 126, 213, 16, 115, 68, 217, 58, 108, 56, 218, 5, 78, 28, 128, 113, 208, 61, 56, 10, 87, 187, 162, 233, 38}
 rijnAlg.IV = {33, 241, 14, 16, 103, 18, 14, 248, 4, 54, 18, 5, 60, 76, 16, 191}
 Dim decryptor As ICryptoTransform
 decryptor = rijnAlg.CreateDecryptor(rijnAlg.Key, rijnAlg.IV)

 Response.Write(rijnAlg.Key)
 Response.Write(rijnAlg.IV)

 Dim rStream As FileStream
 rStream = File.OpenRead("C:test.xml")

 Dim cStream As CryptoStream
 cStream = New CryptoStream(rStream, decryptor, CryptoStreamMode.Read)

 Dim xReader As XmlTextReader
 xReader = New XmlTextReader(cStream)

 Dim xDoc As XDocument
 xDoc = XDocument.Load(xReader)

 xDoc.Save("C:test.xml")
  

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

 Dim XMLDoc As XDocument
    XMLDoc = New XDocument(
        New XDeclaration("1.0", "utf-8", "yes"),
        New XElement("user",
            New XElement("details",
                New XElement("firstname", Firstname.Text),
                New XElement("surname", Lastname.Text)
            )
        )
    )

 XMLDoc.Save("C:test.xml")
  

Ответ №1:

Вы только закрываете / удаляете FileStream , а не CryptoStream или StreamWriter . Это не дает CryptoStream возможности очистить свой последний блок.

Лично я бы использовал Using инструкции для всех из них, после чего все будет закрыто автоматически, и я подозреваю, что вы обнаружите, что это работает нормально. Это также означает, что ваши ресурсы будут освобождены, если возникнет исключение — на данный момент вы ничего не закрываете, например, при сбое записи.

Я бы также не стал заморачиваться с StreamWriter — вместо этого просто сохранял непосредственно в CryptoStream . В противном случае вы получите как XML , так и StreamWriter попытку контролировать используемую кодировку.

Комментарии:

1. Однако это не позволило бы мне закрыть другие потоки. Я попробую использовать метод Using и дам вам знать, как я поступлю. Спасибо.

2. @user718341: Что значит «не позволил бы»? Я предполагаю, что вы пытались закрыть их в неправильном порядке, и они пытались сбросить в закрытый файловый поток…

3. «не позволил бы мне» = получены ошибки. Нет, я изменил порядок — я просто предположил, что это означало, что закрытие последнего используемого разделилось на остальные.

4. @user718341: «есть ошибки» так же расплывчато, как «не позволил бы мне». Какие ошибки? Время компиляции или время выполнения? И да, если бы вы действительно закрыли последний файл ( sWriter ), все было бы в порядке. Но вы закрываете первый ( wStream ).

5. Хорошо, очистка и закрытие сработали. Огромное спасибо, приятель. Я также рассмотрю инструкции Using и исправлю количество потоков.

Ответ №2:

Большое спасибо Джону Скиту, который указал на лучшее решение моих проблем. Окончательный код (и улучшения):

Encrypt.aspx

 Using ra As RijnDaelManaged = RijndaelManaged.Create()

    ra.Key = {118, 123, 23, 17, 161, 152, 35, 68, 126, 213, 16, 115, 68, 217, 58, 108, 56, 218, 5, 78, 28, 128, 113, 208, 61, 56, 10, 87, 187, 162, 233, 38}
    ra.IV = {33, 241, 14, 16, 103, 18, 14, 248, 4, 54, 18, 5, 60, 76, 16, 191}

    encrypt = ra.CreateEncryptor(ra.Key, ra.IV)

    Using ws As FileStream = File.Open("C:test1.xml", FileMode.Create)

        Using cs As CryptoStream = New CryptoStream(ws, encrypt, CryptoStreamMode.Write)

            XMLDoc.Save(cs)

        End Using

    End Using

End Using
  

Расшифровать.aspx

 Using ra As RijndaelManaged = RijndaelManaged.Create()

    ra.Key = {118, 123, 23, 17, 161, 152, 35, 68, 126, 213, 16, 115, 68, 217, 58, 108, 56, 218, 5, 78, 28, 128, 113, 208, 61, 56, 10, 87, 187, 162, 233, 38}
    ra.IV = {33, 241, 14, 16, 103, 18, 14, 248, 4, 54, 18, 5, 60, 76, 16, 191}

    decrypt = ra.CreateDecryptor(ra.Key, ra.IV)

    Using rs As FileStream = File.OpenRead("C:test1.xml")

        Using cs As CryptoStream = New CryptoStream(rs, decrypt, CryptoStreamMode.Read)

            Using xr As XmlTextReader = New XmlTextReader(cs)

                xDoc = XDocument.Load(xr)
                xDoc.Save("C:test2.xml")

            End Using

        End Using

    End Using

End Using