Я пытаюсь зашифровать очень длинный текст, используя общедоступные и закрытые ключи сертификата X509. В частности, я пытаюсь воспроизвести этот код MSDN: https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.publickey(v=vs.90).aspxMemoryStream: Encoding
Однако вместо шифрования файла я хочу зашифровать строку. Поэтому я пытаюсь адаптировать код для использования MemoryStreams.
Проблема в том, что каждый раз, когда я пытаюсь прочитать содержимое потока, у него есть странные символы. Поэтому, когда я пытаюсь вызвать webservice (asmx) и отправив ему шифрованный текст, он выходит из строя.
Это мой код. Я попытался использовать UTF32, UTF8, UTF7 и ASCII.
Private Shared Function encryptText(ByVal token As String, ByVal rsaPublicKey As Security.Cryptography.RSACryptoServiceProvider) As String
Dim aesManaged As New Security.Cryptography.AesManaged()
Dim transform As Security.Cryptography.ICryptoTransform = Nothing
Dim outStreamEncrypted As Security.Cryptography.CryptoStream = Nothing
Dim outFsaux As New IO.MemoryStream()
Dim outFs As New IO.StreamWriter(outFsaux, Text.Encoding.ASCII)
Dim inFs As New IO.MemoryStream(Text.Encoding.ASCII.GetBytes(token))
Dim cipherText As String = String.Empty
Try
aesManaged.KeySize = 256
aesManaged.BlockSize = 128
aesManaged.Mode = Security.Cryptography.CipherMode.CBC
Dim keyFormatter As New Security.Cryptography.RSAPKCS1KeyExchangeFormatter(rsaPublicKey)
Dim keyEncrypted As Byte() = keyFormatter.CreateKeyExchange(aesManaged.Key, aesManaged.GetType())
Dim LenK(3) As Byte
Dim LenIV(3) As Byte
Dim lKey As Integer = keyEncrypted.Length
LenK = BitConverter.GetBytes(lKey)
Dim lIV As Integer = aesManaged.IV.Length
LenIV = BitConverter.GetBytes(lIV)
outFs.Write(LenK)
outFs.Write(LenIV)
outFs.Write(keyEncrypted)
outFs.Write(aesManaged.IV)
transform = aesManaged.CreateEncryptor()
outStreamEncrypted = New Security.Cryptography.CryptoStream(outFs.BaseStream, transform, Security.Cryptography.CryptoStreamMode.Write)
Dim count As Integer = 0
Dim offset As Integer = 0
Dim blockSizeBytes As Integer = aesManaged.BlockSize/8
Dim data(blockSizeBytes) As Byte
Dim bytesRead As Integer = 0
Do
count = inFs.Read(data, 0, blockSizeBytes)
offset += count
outStreamEncrypted.Write(data, 0, count)
bytesRead += blockSizeBytes
Loop While count > 0
inFs.Flush()
outStreamEncrypted.FlushFinalBlock()
outFsaux.Position = 0
cipherText = System.Convert.ToBase64String(outFsaux.ToArray())
Finally
If inFs IsNot Nothing Then inFs.Dispose()
If outFs IsNot Nothing Then outFs.Dispose()
If outStreamEncrypted IsNot Nothing Then outStreamEncrypted.Dispose()
If transform IsNot Nothing Then transform.Dispose()
End Try
Return cipherText
End Function
ОБНОВЛЕНИЕ:
Спасибо за помощь. Я также обновил вышеуказанный код.
Теперь я могу правильно шифровать текст. Тем не менее, мне все еще нужна помощь, чтобы адаптировать метод дешифрования. Он сбой при попытке создать переменную KeyDecrypted
Я знаю, что проблема заключается в том, что при шифровании он загружает некоторую информацию в начале строки шифрования, способ дешифрования которой невозможно восстановить должным образом после преобразования Base64.
Private Shared Function decryptText(ByVal token As String, ByVal rsaPrivateKey As Security.Cryptography.RSACryptoServiceProvider) As String
Dim aesManaged As New Security.Cryptography.AesManaged()
Dim inFs As IO.MemoryStream = New IO.MemoryStream(Convert.FromBase64String(token))
Dim outFs As New IO.MemoryStream
Dim outStreamDecrypted As Security.Cryptography.CryptoStream = Nothing
Dim decipherText As String = String.Empty
aesManaged.KeySize = 256
aesManaged.BlockSize = 128
aesManaged.Mode = Security.Cryptography.CipherMode.CBC
Dim LenK() As Byte = New Byte(4 - 1) {}
Dim LenIV() As Byte = New Byte(4 - 1) {}
inFs.Seek(0, IO.SeekOrigin.Begin)
inFs.Seek(0, IO.SeekOrigin.Begin)
inFs.Read(LenK, 0, 3)
inFs.Seek(4, IO.SeekOrigin.Begin)
inFs.Read(LenIV, 0, 3)
Dim lengthK As Integer = BitConverter.ToInt32(LenK, 0)
Dim lengthIV As Integer = BitConverter.ToInt32(LenIV, 0)
Dim startC As Integer = lengthK + lengthIV + 8
Dim lenC As Integer = (CType(inFs.Length, Integer) - startC)
Dim KeyEncrypted() As Byte = New Byte(lengthK - 1) {}
Dim IV() As Byte = New Byte(lengthIV - 1) {}
inFs.Seek(8, IO.SeekOrigin.Begin)
inFs.Read(KeyEncrypted, 0, lengthK)
inFs.Seek(8 + lengthK, IO.SeekOrigin.Begin)
inFs.Read(IV, 0, lengthIV)
Dim KeyDecrypted As Byte() = rsaPrivateKey.Decrypt(KeyEncrypted, False)
Dim transform As Security.Cryptography.ICryptoTransform = aesManaged.CreateDecryptor(KeyDecrypted, IV)
Dim count As Integer = 0
Dim offset As Integer = 0
Dim blockSizeBytes As Integer = aesManaged.BlockSize/8
Dim data(blockSizeBytes) As Byte
inFs.Seek(startC, IO.SeekOrigin.Begin)
outStreamDecrypted = New Security.Cryptography.CryptoStream(outFs, transform, Security.Cryptography.CryptoStreamMode.Write)
Do
count = inFs.Read(data, 0, blockSizeBytes)
offset += count
outStreamDecrypted.Write(data, 0, count)
Loop While count > 0
outFs.Position = 0
Using rd As New IO.StreamReader(outFs)
decipherText = rd.ReadToEnd()
End Using
Return decipherText
End Function
Результатом зашифрованного текста являются произвольные байты. Они могут * не * быть преобразованы в текст, ваш вызов StreamReader.ReadToEnd() будет случайным образом разбивать или уничтожать зашифрованные байтовые значения. Кодирование с Convert.ToBase64String() - общий подход. –
@ HansPassant Спасибо за помощь. Я был бы рад Если бы вы могли проверить обновление – Rumpelstinsk