Chat freely about anything...

User avatar
By veljani
#45925 I'm trying to connect ESP and RPI (windows IOT) over secure connection (AES.CBC crypt)
This is VB2015 code that works:
Code: Select all    Public Function Encrypt(dataToEncrypt As String, password As String, salt As String) As String
        ' Generate a key and IV from the password and salt
        Dim aesKeyMaterial As IBuffer
        Dim iv As IBuffer
        Dim iterationCount As UInteger = 10000
        GenerateKeyMaterial(password, salt, iterationCount, aesKeyMaterial, iv)

        Dim plainText As IBuffer = CryptographicBuffer.ConvertStringToBinary(dataToEncrypt, BinaryStringEncoding.Utf8)

        ' Setup an AES key, using AES in CBC mode and applying PKCS#7 padding on the input
        Dim aesProvider As SymmetricKeyAlgorithmProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7)
        Dim aesKey As CryptographicKey = aesProvider.CreateSymmetricKey(aesKeyMaterial)

        ' Encrypt the data and convert it to a Base64 string
        Dim encrypted As IBuffer = CryptographicEngine.Encrypt(aesKey, plainText, iv)
        'IBuffer buffUTF8 = CryptographicBuffer.ConvertStringToBinary(strIn, BinaryStringEncoding.Utf8);
        Return CryptographicBuffer.EncodeToBase64String(encrypted)
    End Function

    Public Function Decrypt(dataToDecrypt As String, password As String, salt As String) As String
        ' Generate a key and IV from the password and salt
        Dim aesKeyMaterial As IBuffer
        Dim iv As IBuffer
        Dim iterationCount As UInteger = 10000
        GenerateKeyMaterial(password, salt, iterationCount, aesKeyMaterial, iv)

        ' Setup an AES key, using AES in CBC mode and applying PKCS#7 padding on the input
        Dim aesProvider As SymmetricKeyAlgorithmProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7)
        Dim aesKey As CryptographicKey = aesProvider.CreateSymmetricKey(aesKeyMaterial)

        ' Convert the base64 input to an IBuffer for decryption
        Dim ciphertext As IBuffer = CryptographicBuffer.DecodeFromBase64String(dataToDecrypt)

        ' Decrypt the data and convert it back to a string
        Dim decrypted As IBuffer = CryptographicEngine.Decrypt(aesKey, ciphertext, iv)
        Dim decryptedArray As Byte() = decrypted.ToArray()
        Return Encoding.UTF8.GetString(decryptedArray, 0, decryptedArray.Length)
    End Function

    Private Sub GenerateKeyMaterial(password As String, salt As String, iterationCount As UInteger, ByRef keyMaterial As IBuffer, ByRef iv As IBuffer)
        ' Setup KDF parameters for the desired salt and iteration count
        Dim saltBuffer As IBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf8)
        Dim kdfParameters As KeyDerivationParameters = KeyDerivationParameters.BuildForPbkdf2(saltBuffer, iterationCount)

        ' Get a KDF provider for PBKDF2, and store the source password in a Cryptographic Key
        Dim kdf As KeyDerivationAlgorithmProvider = KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha256)
        Dim passwordBuffer As IBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8)
        Dim passwordSourceKey As CryptographicKey = kdf.CreateKey(passwordBuffer)

        ' Generate key material from the source password, salt, and iteration count.  Only call DeriveKeyMaterial once,
        ' since calling it twice will generate the same data for the key and IV.
        Dim keySize As Integer = 128 / 8 '256 / 8
        Dim ivSize As Integer = 128 / 8
        Dim totalDataNeeded As UInteger = CUInt(keySize + ivSize)
        Dim keyAndIv As IBuffer = CryptographicEngine.DeriveKeyMaterial(passwordSourceKey, kdfParameters, totalDataNeeded)

        ' Split the derived bytes into a seperate key and IV
        Dim keyMaterialBytes As Byte() = keyAndIv.ToArray()
        keyMaterial = WindowsRuntimeBuffer.Create(keyMaterialBytes, 0, keySize, keySize)
        iv = WindowsRuntimeBuffer.Create(keyMaterialBytes, keySize, ivSize, ivSize)
    End Sub

Usage:
Code: Select all    Dim encryptString As String = Encrypt("my text", "mypassword", "mysalt")
    Dim decryptString As String = Decrypt(encryptString, "mypassword", "mysalt")

And it works fine.
How can now I use this with ESP8266? I don't have any idea how to use crypto library. Let say that ESP and RaspberryPI will exchange keys at initial setup. What after that? I cannot make VB encrypt string and ESP crypto string the same...

Any suggestion?
User avatar
By veljani
#45930 Edit (Simplified code without IV):
Code: Select all   Public Function Encrypt(key As String, value As String) As String
        ' Private key has to be exactly 16 characters
        If key.Length > 16 Then
            ' Cut of the end if it exceeds 16 characters
            key = key.Substring(0, 16)
        Else
            ' Append zero to make it 16 characters if the provided key is less
            While key.Length < 16
                key += "0"
            End While
        End If

        ' We'll be using AES, CBC mode with PKCS#7 padding to encrypt
        Dim aesCbcPkcs7 As SymmetricKeyAlgorithmProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7)

        ' Convert the private key to binary
        Dim keymaterial As IBuffer = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8)

        ' Create the private key
        Dim k As CryptographicKey = aesCbcPkcs7.CreateSymmetricKey(keymaterial)

        ' Creata a 16 byte initialization vector
        Dim iv As IBuffer = keymaterial

        ' Encrypt the data
        Dim plainText As Byte() = Encoding.UTF8.GetBytes(value)
        ' Data to encrypt
        Dim buff As IBuffer = CryptographicEngine.Encrypt(k, CryptographicBuffer.CreateFromByteArray(plainText), iv)


        Return CryptographicBuffer.EncodeToBase64String(buff)
    End Function

    ''' <summary>
    ''' Decrypt a string
    ''' </summary>
    ''' <param name="key">Private key</param>
    ''' <param name="value">Encrypted string in Base64 format</param>
    ''' <returns>Original value</returns>
    Public Function Decrypt(key As String, value As String) As String
        If key.Length > 16 Then
            key = key.Substring(0, 16)
        Else
            ' Fill key
            While key.Length < 16
                key += "0"
            End While
        End If


        Dim val As IBuffer = CryptographicBuffer.DecodeFromBase64String(value)

        ' Use AES, CBC mode with PKCS#7 padding (good default choice)
        Dim aesCbcPkcs7 As SymmetricKeyAlgorithmProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7)

        Dim keymaterial As IBuffer = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8)

        ' Create an AES 128-bit (16 byte) key
        Dim k As CryptographicKey = aesCbcPkcs7.CreateSymmetricKey(keymaterial)

        ' Creata a 16 byte initialization vector
        Dim iv As IBuffer = keymaterial
        ' CryptographicBuffer.GenerateRandom(aesCbcPkcs7.BlockLength);
        'IBuffer val = CryptographicBuffer.DecodeFromBase64String(value);

        Dim buff As IBuffer = CryptographicEngine.Decrypt(k, val, iv)

        Return CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, buff)

    End Function


Example:
Dim a = Encrypt("1234567890abcdef", "proba")
gives:
"lwubrPZecSCWVVVDa5It9w=="

ESP8266 code:
Code: Select allproba=crypto.encrypt("AES-CBC", "1234567890abcdef", "proba")
print(proba)
b64 = crypto.toBase64(proba)
print(b64)

gives:
"IdxV+dTT+O93ovQST/C4Tg=="

What I'm doing wrong?!?