Совместимость шифрования между Obj-C и VB.Net
Существует около 100 000 различных способов шифрования строки. Использование таких стандартов, как AES, CBC и PKCS7, облегчает задачу, но все еще существуют проблемы с IVs. Соли, кодирование и т. д. (Как отмечено на www.Crypto.Stackexchange.com )
Для моего проекта iOS (Obj-C) я использую проект FBEncryptor, который является простым и хорошо документированным способом шифрования строк. Однако мне нужен код, который сможет расшифровать эту строку iOS AES, сгенерированную FBEncryptor на a Платформа Windows-предпочтительно VB.NET.
Мне еще предстоит найти другой проект для VB.NET это совместимо с FBEncryptor.
Кто-нибудь знает о них? VB.NET проекты шифрования, работающие с FBEncryptor? Если нет, то что мне нужно сделать, чтобы управляемая библиотека Rijndael (предоставленная Microsoft) работала с FBEncryptor?
Мой VB.NET код с использованием Rijndael Managed:
Imports System.Security
Imports System.Security.Cryptography
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text.RegularExpressions
Imports System.Text
Module Encrypt2
Public saltBytes As Byte()
Dim hashAlgorithm As String = "SHA1"
Public Sub GenerateSalt()
' Define min and max salt sizes.
Dim minSaltSize As Integer
Dim maxSaltSize As Integer
minSaltSize = 8
maxSaltSize = 8
' Generate a random number for the size of the salt.
Dim random As Random
random = New Random()
Dim saltSize As Integer
saltSize = random.Next(minSaltSize, maxSaltSize)
' Allocate a byte array, which will hold the salt.
saltBytes = New Byte(saltSize - 1) {}
' Initialize a random number generator.
Dim rng As RNGCryptoServiceProvider
rng = New RNGCryptoServiceProvider()
' Fill the salt with cryptographically strong byte values.
rng.GetNonZeroBytes(saltBytes)
End Sub
Public Function Encrypt(ByVal plainText As String, ByVal keyword As String) As String
Dim hashAlgorithm As String = "SHA1"
Dim passwordIterations As Integer = 128
Dim initVector As String = "@7781157e2629b09"
Dim keySize As Integer = 256
Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(initVector)
Dim plainTextBytes As Byte() = Encoding.ASCII.GetBytes(plainText)
GenerateSalt()
Dim password As New Rfc2898DeriveBytes(keyword, saltBytes, passwordIterations)
Dim keyBytes As Byte() = password.GetBytes(keySize 8)
Dim symmetricKey As New RijndaelManaged()
symmetricKey.Mode = CipherMode.CBC
Dim encryptor As ICryptoTransform = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)
Dim memoryStream As New MemoryStream()
Dim cryptoStream As New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)
cryptoStream.FlushFinalBlock()
Dim cipherTextBytes As Byte() = memoryStream.ToArray()
memoryStream.Close()
cryptoStream.Clear()
Dim cipherText As String = Convert.ToBase64String(cipherTextBytes)
Return (cipherText)
End Function
Public Function Decrypt(ByVal cipherText As String, ByVal keyword As String) As String
Dim hashAlgorithm As String = "SHA1"
Dim passwordIterations As Integer = 128
Dim initVector As String = "@7781157e2629b09"
Dim keySize As Integer = 256
' Convert strings defining encryption key characteristics into Byte
' arrays. Let us assume that strings only contain ASCII codes.
' If strings include Unicode characters, use Unicode, UTF7, or UTF8
' encoding
Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(initVector)
' Convert the Ciphertext into a Byte array
Dim cipherTextBytes As Byte() = Encoding.ASCII.GetBytes(cipherText)
' First we must create a password, from which the key will be
' derived. This password will be generated from the specified
' passphrase and salt value. The password will be created using
' the specified hash algorithm. Password creation can be done in
' several iterations
GenerateSalt()
Dim password As New Rfc2898DeriveBytes(keyword, saltBytes, passwordIterations)
' Use the password to generate pseudo-random bytes for the encryption
' key. Specify the size of the key in bytes (instead of bits)
Dim keyBytes As Byte() = password.GetBytes(keySize 8)
' Create uninitialized Rijndael encryption object
Dim symmetricKey As New RijndaelManaged()
' It is reasonable to set encryption mode to Cipher Block Chaining
' (CBC). Use default options for other symmetric key parameters.
symmetricKey.Mode = CipherMode.CBC
' Generate decryptor from the existing key bytes and initialization
' vector. Key size will be defined based on the number of the key
'bytes
Dim decryptor As ICryptoTransform = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)
' Define memory stream which will be used to hold encrypted data.
Dim memoryStream As New MemoryStream(cipherTextBytes)
' Define cryptographic stream (always user Read mode for encryption).
Dim cryptoStream As New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
' Since at this point we don't know what the size of decrypted data
' will be, allocate the buffer long enough to hold ciphertext;
' plaintext is never longer than ciphertext
Dim plainTextBytes As Byte() = New Byte(cipherTextBytes.Length - 1) {}
' Start decrypting.
Dim decryptedByteCount As Integer = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length)
' Close both streams
memoryStream.Close()
cryptoStream.Close()
' Convert decrypted data into a string
' Let us assume that the original plaintext string was UTF8-Encoded.
Dim plainText As String = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount)
' Return the decrypted string
Return (plainText)
End Function
End Module
Вы заметите, что капельница статична и что пароль итерации невелики. Это потому, что я не уверен, как генерировать IV тем же методом, что и FBEncryptor. Вы также можете заметить, что при попытке расшифровки возникают проблемы с длиной байта.
Любая помощь будет оценена по достоинству! Спасибо!
1 ответ:
Одна нота. Я заглянул в FBEncryptor. Он использует некоторые плохие практики. Поэтому, если безопасность важна для вас, я бы рекомендовал прочитать немного больше об этом и выбрать другой код, который делает шифрование (или написать его самостоятельно).
FBEncryptor делает следующее для шифрования а) преобразование строки в массив байтов (на основе кодировки UTF8) b) преобразование ключа в массив байтов (на основе кодировки UTF). c) копировать только первые 16 байт ключа d) создать IV, который равен 16 битам 0x00 е) шифрование байт массив из пункта а) используя AES/CBC/PKCS7Padding с IV, созданным в d) f) полученные зашифрованные данные преобразуются в Base64
И он делает следующее для расшифровки a) преобразование строки шифрования из Base64 в массив байтов b) преобразование ключа в массив байтов (на основе кодировки UTF). c) копировать только первые 16 байт ключа d) создать IV, который равен 16 битам 0x00 e) расшифровать массив байтов из пункта a) используя AES/CBC/PKCS7Padding с IV, созданным в d) f) преобразование зашифрованных данных из e) в строку с помощью UTF8 кодировка
Вы должны сделать точно то же самое в VB.NET я думаю, что у вас есть почти все части - Вам нужно будет отбросить все SHA1 и связанные с солью вещи и использовать эквивалент шага b). И вам нужно будет исследовать PKCS7Padding для VB.NET