Encryption across all Xojo platforms, including iOS

  1. 7 weeks ago

    David C

    Jan 8 Pre-Release Testers, Xojo Pro, XDC Speakers Derby, ITM

    I have used Einhugur (AES CBC) to encrypt sensitive fields in my databases on desktop, console and web for years. Now I want to create an iOS version of my app and decrypt those fields.
    Here is my dilemma:

    1. MBS Encryption Kit works, but supports only iOS and macOS ie no Windows or Linux
    2. Einhugur and M_Crypto support only desktop, console and web ie no iOS

    So I need a multi-provider solution ie MBS Encryption Kit and one other. So I wrote a simple piece of code to encrypt a sample string with a password key and an IV Key, then HexEncode it, assuming they would all return the same Hex. Boy was I wrong! Every system produces different Hex results. Given they are all using public libraries behind the scenes, either my code is wrong or I am missing something. The Hex code is in the comment line after each encryption.

    As MBS Encryption Kit is the only game in town for iOS encryption (that I know of), I need a Windows, Linux encryption solution that can encrypt/decrypt the text in the same way as the MBS Encryption Kit. I was hoping M_Crypto was this solution.

    Can someone either tell me what I am doing wrong or inform me of another cross-platform solution that includes iOS?

    Const kInputText As String = "Some Text to encrypt…" '> 0 bytes and less than 4 GBytes
    Dim kMBInputText As Xojo.Core.MemoryBlock = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(kInputText.ToText)
    
    Const kPassword As String = "12345678901234567890123456789012" '32 bytes
    Dim kPasswordText As Text = kPassword.ToText
    Dim mbPasswordHash As Xojo.Core.MemoryBlock = CommonCryptoMB.Hash(CommonCryptoMB.Hashes.SHA256, kPasswordText)
    Dim mbPassword As Xojo.Core.MemoryBlock = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(kPassword.ToText)
    
    Const kIVKey As String = "1234567890123456" '16 bytes
    Dim mbIVKey As Xojo.Core.MemoryBlock = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(kIVKey.ToText)
    Dim mbIVKeyEmpty As Xojo.Core.MemoryBlock
    
    Dim returnText As Text
    Dim returnString As String
    
    'MBS Encryption Kit for macOS and iOS only
    Dim Encryptor As New CommonCryptorMB(CommonCryptoMB.CryptoOperation.Encrypt, CommonCryptoMB.CryptoMode.kCCModeCBC, CommonCryptoMB.CryptoAlgorithm.AES, CommonCryptoMB.CryptoPadding.PKCS7, kPasswordText, mbIVKey)
    Dim enData1 As Xojo.Core.MemoryBlock = Encryptor.Update(kMBInputText)
    Dim enData2 As Xojo.Core.MemoryBlock = Encryptor.Final1
    Dim EncryptedData As New Xojo.Core.MutableMemoryBlock(enData1)
    EncryptedData.Append(enData2)
    returnText = CommonCryptoMB.EncodeHex(encryptedData)
    // 1B25F04DF6A1B0091AFDA65BFE2963BCB98E44277D21C06E8E19FD9A9AE6A1EE
    
    'M_Crypto for macOS, Windows and Linux on desktop, console and web only
    Dim bf As Blowfish_MTC
    bf = New Blowfish_MTC(kPassword, Blowfish_MTC.Padding.PKCS)
    bf.SetInitialVector kIVKey
    returnString = EncodeHex(bf.EncryptCBC(kInputText))
    // A641C0421611BB9B14753C62D6D181A5DAADAFB240A3FDCF
    
    'M_Crypto for macOS, Windows and Linux on desktop, console and web only
    Dim tempAES_MTC As AES_MTC
    tempAES_MTC = New AES_MTC(kPasswordText, AES_MTC.EncryptionBits.Bits192, AES_MTC.Padding.PKCS)
    tempAES_MTC.SetInitialVector(kIVKey)
    returnString = EncodeHex(tempAES_MTC.EncryptCBC(kInputText))
    // E006D62B6DB2734C2BB2105DC7B949471C2F8C771F1D979DBBEF6D987A883CA0 as Bits128
    // 2163D24D8B14F0CE64AE87CB391E7BA96B07C88003C2851B247FAA7AD8F43C78 as Bits192
    // 0B8B533D0C6F6A016A9FCB97C82B875513AFFA8640F966BFBD09A028AE0199ED as Bits256
    
    'Einhugur for macOS, Windows and Linux on desktop, console and web only
    Dim tempAES_CBC As AES_CBC
    tempAES_CBC = New AES_CBC(kPassword, kIVKey)
    returnString = EncodeHex(tempAES_CBC.Encrypt(kInputText) + tempAES_CBC.FinishEncrypt)
    // 0B8B533D0C6F6A016A9FCB97C82B875572797074E280A6 'same as M_Crypto 256 bit for first 32 Hex bytes
    
    'Einhugur for macOS, Windows and Linux on desktop, console and web only
    Dim twoFish As New TwofishCBC(kPassword, 0, kIVKey) '0=Encrypt, 1=Decrypt, 2=Don't know
    returnString = EncodeHex(twoFish.Encrypt(kInputText) + twoFish.FinishEncrypt)
    // E50E715116917951B659508FABD6F8CC72797074E280A6

    Here is the final code to encrypt and decrypt across desktop, web, console AND iOS using MBS Encryption plugins and the MBS Encryption Kit.

    Sorry I cannot include a full example since it requires a purchase from MBS. I have sent full working examples for desktop, web, console and iOS to Christian in case he wants to include it within his product.

    I have only included encryption and decryption here, but I have also used it in conjunction with Christians ZipMBS and iOS Zip routines to allow your text or binary data to be compressed before encryption, if desired. This also works cross desktop, web, console and iOS.

    I have used this zipping and compressing to successfully send a componentised SQL command as JSON from iOS to Aloe Express (runs on desktop, web or console) via an HTTP Socket, where it runs the SQL Command (SELECT, INSERT, UPDATE or DELETE), and returns the results (after JSON'ing the RecordSet and error message, zipping and encrypting) then undoing it all again on the iOS device, to return a RecordSet to your iOS app as if you had just retrieved it from a local SQLite database!

    Protected Function Encrypt(UnencryptedData As Xojo.Core.MemoryBlock, PasswordKey As Text, IVKey As Text, SaltSize As Integer = 8) as Text
      #If TargetiOS Then 'iOS and macOS only
        // create the salt and generate a 64 character CheckHash
        Dim Salt As Xojo.Core.MemoryBlock = CommonCryptoMB.generateBytes1(SaltSize)
        Dim CheckHash As Xojo.Core.MemoryBlock = CommonCryptoMB.Hash(CommonCryptoMB.Hashes.SHA512, UnencryptedData)
        
        // get hash of key
        Dim KeyHash As Xojo.Core.MemoryBlock = HashKey(PasswordKey)
        
        // set to encrypt
        Dim Operation As CommonCryptoMB.CryptoOperation = CommonCryptoMB.CryptoOperation.Encrypt
        
        // AES
        Dim Algorithm As CommonCryptoMB.CryptoAlgorithm = CommonCryptoMB.CryptoAlgorithm.AES
        
        // CBC mode and padding
        Dim Options As Integer = BitWiseOR(CommonCryptoMB.kCCOptionPKCS7Padding, CommonCryptoMB.kCCOptionCBCMode)
        
        // IV Key
        Dim IV As Xojo.Core.MemoryBlock
        If IVKey <> "" Then 'leave as nil?
          IV = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(IVKey)
        End If
        
        // get data to encrypt as memoryblock
        Dim EncryptedData As Xojo.Core.MemoryBlock = CommonCryptoMB.Crypt(Operation, Algorithm, Options, KeyHash, UnencryptedData, IV)
        
        // append salt and check Hash
        Dim tempMutableMemoryBlock As New Xojo.Core.MutableMemoryBlock(Salt)
        tempMutableMemoryBlock.Append(EncryptedData)
        tempMutableMemoryBlock.Append(CheckHash)
        
        Return CommonCryptoMB.EncodeBase64Memory(New Xojo.Core.MemoryBlock(tempMutableMemoryBlock))
        
      #Else 'macOS, Windows, Linux, desktop, web, console only, but not iOS
        // via MBS Encryption Plugin for Mac/Windows/Linux
        Dim Salt As String = RandomBytesStringMBS(SaltSize)
        Var tempMemoryBlock As MemoryBlock = UnencryptedData.Data 'convert from Xojo.Core.MemoryBlock to MemoryBlock to String
        Dim InputData As String = tempMemoryBlock.StringValue(0, UnencryptedData.Size) 'cannot use TextEncoding.UTF8 as it might be binary data
        tempMemoryBlock = nil 'clear the RAM
        Dim CheckHash As String = SHA512MBS.Hash(InputData)
        
        // get key
        Dim KeyHash As String = SHA256MBS.Hash(PasswordKey)
        
        // encrypt
        Dim ecipher As CipherMBS = CipherMBS.aes_256_cbc
        
        // IV Key
        Dim IV As MemoryBlock
        If IVKey <> "" Then 'leave as nil?
          IV = IVKey
        End If
        
        If ecipher.EncryptInit(KeyHash, IV) Then 'change Nil to IV later!
          ecipher.Padding = True
          Dim EncryptedData As String = ecipher.ProcessString(InputData) + ecipher.FinalizeAsString
          
          Return EncodeBase64MBS(Salt + EncryptedData + CheckHash, 0, "").ToText
          
        Else
          Return ""
        End If
      #EndIf
          
    End Function
    Protected Function Decrypt(EncryptedBase64 As Text, PasswordKey As Text, IVKey As Text, SaltSize As Integer = 8) as Text
      #If TargetiOS Then 'iOS and macOS only
        // don't need to create Salt
        
        // get hash of key
        Dim KeyHash As Xojo.Core.MemoryBlock = HashKey(PasswordKey)
        
        // set to decrypt
        Dim Operation As CommonCryptoMB.CryptoOperation = CommonCryptoMB.CryptoOperation.Decrypt
        
        // AES
        Dim Algorithm As CommonCryptoMB.CryptoAlgorithm = CommonCryptoMB.CryptoAlgorithm.AES
        
        // CBC mode and padding
        Dim Options As Integer = BitWiseOR(CommonCryptoMB.kCCOptionPKCS7Padding, CommonCryptoMB.kCCOptionCBCMode)
        
        // IV Key
        Dim IV As Xojo.Core.MemoryBlock
        If IVKey <> "" Then 'leave as nil?
          IV = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(IVKey)
        End If
        
        // get data to decrypt as memoryblock
        Dim EncryptedData As Xojo.Core.MemoryBlock = CommonCryptoMB.DecodeBase64Memory(EncryptedBase64)
        
        // remove salt and check Hash
        Dim CheckHash As Xojo.Core.MemoryBlock = EncryptedData.Right(64)
        EncryptedData = EncryptedData.Mid(SaltSize, EncryptedData.Size - 64 - SaltSize) 'remove Salt and CheckHash, zero-based so start from character #8
        
        Dim DecryptedData As Xojo.Core.MemoryBlock = CommonCryptoMB.Crypt(Operation, Algorithm, Options, KeyHash, EncryptedData, IV)
        
        If CheckHash <> CommonCryptoMB.Hash(CommonCryptoMB.Hashes.SHA512, DecryptedData) Then 'check that the Hash is still correct ie the text has not been tampered with
          Return ""
        End If
        
        'Return DecryptedData
        Return CommonCryptoMB.EncodeBase64Memory(DecryptedData)
        
      #Else 'macOS, Windows, Linux, desktop, web, console only, but not iOS
        // don't need to create Salt
        
        // get hash of key
        Dim KeyHash As String = SHA256MBS.Hash(PasswordKey)
        
        // get data to decrypt as String
        Dim EncryptedData As String = DecodeBase64MBS(EncryptedBase64)
        
        // remove salt and check Hash
        Dim CheckHash As String = EncryptedData.RightB(64)
        EncryptedData = EncryptedData.MiddleBytes(SaltSize, EncryptedData.LenB - 64 - SaltSize) 'remove Salt and CheckHash, zero-based so start from character #8
        
        // IV Key
        Dim IV As MemoryBlock
        If IVKey <> "" Then 'leave as nil?
          IV = IVKey
        End If
        
        // now decrypt
        Dim dcipher As CipherMBS = CipherMBS.aes_256_CBC
        If dcipher.DecryptInit(KeyHash, IV) Then 'change Nil to IV later!
          dcipher.Padding = True
          
          Dim DecryptedData As String = dcipher.ProcessString(EncryptedData) + dcipher.FinalizeAsString
          
          If CheckHash <> SHA512MBS.Hash(DecryptedData) Then 'check that the Hash is still correct ie the text has not been tampered with
            Return ""
          End If
          
          Return EncodeBase64MBS(DecryptedData, 0, "").ToText 'use Base64 since Xojo.Core.MemoryBlock sometimes gets corrupted
          
        End If
      #EndIf
          
    End Function
  2. Kevin G

    Jan 8 Pre-Release Testers, Xojo Pro Gatesheed, England

    Check the length of your password / secret.
    If the length does not match what the encryption algorithm requires, the plugin / module will either be truncating it or padding it to the required size. I imagine different suppliers will use a different approach for this.

  3. Christian S

    Jan 8 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    did you try MBS Encryption Plugin For Mac, Windows and Linux?

  4. Jürg O

    Jan 8 Pre-Release Testers, Xojo Pro
    Edited 7 weeks ago

    @Kevin G Check the length of your password / secret.
    If the length does not match what the encryption algorithm requires, the plugin / module will either be truncating it or padding it to the required size. I imagine different suppliers will use a different approach for this.

    And... the Data you're going to De/Encrypt needs to have an appropriate Block Size for the encryption algorithm.

    @David Cox Const kInputText As String = "Some Text to encrypt…" '> 0 bytes and less than 4 GBytes

    As far as I remember: a multiple of 16 Bytes for AES.

    If the Data you're going to de/encrypt is not a "full Block size", the various suppliers again use different approaches to "fill up" or "handle" the last block.

    I think to remember... that MBS fills up with Zeros (not quite sure if that's correct...). While I know that Einhugur just returns the "not filled up block" as-is (unencrypted).

    So what happens if you AES-Encrypt Data (LenB: 18) using Einhugur (let's assume a Key of valid LenB: 16|24|32):
    The first 16 Bytes are being AES-Encrypted, then the remaining 2 Bytes are just being appended as-is.
    You end up with unencrypted data of an "invalid block size" (Note: I'm not saying Einhugur is wrong - it's the data being used that's wrong, so the Plugin has to do "something").

    If you then try to decrypt that using MBS you need to:

    • detect that the encrypted Data is not a multiple of 16: e.g. by (LenB(encData) mod 16)
    • just decrypt the "full blocks" with MBS, then append the remaining Bytes "as-they-are"

    Because if you just try to decrypt the "invalid sized encrypted data", MBS might (I don't know what MBS is doing in such a situation) fill up with ChrB(0) to the next full block (or just fail, because you've supplied invalid data), and decrypt that - which will obviously be different.

    Long story short:

    • make sure all Keys/Secrets/... have the correct/expected "(block) length" for the used algorithm
    • don't forget that the Data to-be-de/encrypted also needs to be of a valid "block size"!
    • if not... then you need to know how the supplier you've used has handled the "invalid data", and using a "different supplier" to decrypt, you have to make the appropriate steps to get it back.

    I hope I remember that more or less correct... it's been a while when I've been in a similar situation and had to compare how Einhugur and MBS handle AES encryption with "invalid sized data".

  5. Jürg O

    Jan 8 Pre-Release Testers, Xojo Pro
    Edited 7 weeks ago

    @Kevin G Check the length of your password / secret.
    If the length does not match what the encryption algorithm requires, the plugin / module will either be truncating it or padding it to the required size. I imagine different suppliers will use a different approach for this.

    Ah - I remember how MBS and Einhugur handle the AES_ECB and AES_CBC key.
    MBS doesn't allow an invalid length for the key. However, Einhugur does...
    But what does Einhugur do if the Key's LenB is not 16,24,32? That's the big question in your game.

    • smaller than 16: it uses "0000000000000000" (yes, the Number 0, not ChrB(0)). So any invalid key with LenB<16 will have the very same result, as it's using the same key effectively for encryption ;)
    • >16 and < 24: it uses MidB(key, 1, 16)
    • >24 and < 32: it uses MidB(key, 1, 24)
    • >32: it uses MidB(key, 1, 32)

    So again... if you "by mistake" have AES-encrypted Data (of valid size) with Einhugur, but used an "invalid length" key of LenB=12 - then you now know how to decrypt that using MBS ;)

    Otherwise... again: make sure of the lengths.

    My suspiction is in your example above that the data you're encrypting as a test has an invalid "block size".

    You probably want something along these lines:

    • don't encrypt your kInputText!
    • first make sure you've got a valid block size for the Data you're going to encrypt
    • only encrypt valid sized data
    Dim sData As String = kInputText 
    //Fill up to a valid block size
    const AES_BLOCK_SIZE = 16
    Dim iRemainingBytes As Integer = (LenB(sData) mod AES_BLOCK_SIZE)
    for i As Integer = iRemainingBytes to AES_BLOCK_SIZE - 1 - 1
      sData = sData + ChrB(0)
    next
    sData = sData + ChrB(iRemainingBytes)
    
    //now encrypt sData - not kInputText
    
    //Note: after Decrypting, look at the last Byte
    //it will tell you how many ChrB(0) have been added to fill the required AES Block Size
    //cut that away again from the result of the Decryption to get the decrypted original data
  6. David C

    Jan 8 Pre-Release Testers, Xojo Pro, XDC Speakers Derby, ITM

    @ChristianSchmitz did you try MBS Encryption Plugin For Mac, Windows and Linux?

    Yes. Firstly I tried all your samples including Your AES Example. It ran flawlessly on macOS, but gave 21 compile errors on Windows 10 re "Declares directly into the runtime via Lib "" are no longer allowed" and "Objective–C declares can only be called when building for iOS or OS X".

    When I bracketed these methods with #If TargetiOS or TargetMacOS the example was abe to run, but then it caused a break in CommonCryptoMB.Hash and CommonCryptoMB.Crypt leading to a nil encryption result.

    I would love to have it all run in the MBS Encryption Kit.

  7. Jürg O

    Jan 8 Pre-Release Testers, Xojo Pro
    Edited 7 weeks ago

    @ChristianSchmitz MBS Encryption Plugin

    @David C MBS Encryption Kit.

    It‘s not the same...

    @David C CommonCryptoMB.Crypt leading to a nil encryption result

    Again ... maybe invalid block size of data-to-be-encrypted?

  8. Michael D

    Jan 8 Pre-Release Testers, Xojo Pro

    If you can use symmetric encryption then you could do it in pure Xojo code with RC4: https://forum.xojo.com/conversation/post/110903

    cyphertext = RC4(plaintext, key)
    and
    plaintext = RC4(cyphertext, key)

  9. 3 weeks ago

    David C

    Feb 6 Pre-Release Testers, Xojo Pro, XDC Speakers Answer Derby, ITM

    Here is the final code to encrypt and decrypt across desktop, web, console AND iOS using MBS Encryption plugins and the MBS Encryption Kit.

    Sorry I cannot include a full example since it requires a purchase from MBS. I have sent full working examples for desktop, web, console and iOS to Christian in case he wants to include it within his product.

    I have only included encryption and decryption here, but I have also used it in conjunction with Christians ZipMBS and iOS Zip routines to allow your text or binary data to be compressed before encryption, if desired. This also works cross desktop, web, console and iOS.

    I have used this zipping and compressing to successfully send a componentised SQL command as JSON from iOS to Aloe Express (runs on desktop, web or console) via an HTTP Socket, where it runs the SQL Command (SELECT, INSERT, UPDATE or DELETE), and returns the results (after JSON'ing the RecordSet and error message, zipping and encrypting) then undoing it all again on the iOS device, to return a RecordSet to your iOS app as if you had just retrieved it from a local SQLite database!

    Protected Function Encrypt(UnencryptedData As Xojo.Core.MemoryBlock, PasswordKey As Text, IVKey As Text, SaltSize As Integer = 8) as Text
      #If TargetiOS Then 'iOS and macOS only
        // create the salt and generate a 64 character CheckHash
        Dim Salt As Xojo.Core.MemoryBlock = CommonCryptoMB.generateBytes1(SaltSize)
        Dim CheckHash As Xojo.Core.MemoryBlock = CommonCryptoMB.Hash(CommonCryptoMB.Hashes.SHA512, UnencryptedData)
        
        // get hash of key
        Dim KeyHash As Xojo.Core.MemoryBlock = HashKey(PasswordKey)
        
        // set to encrypt
        Dim Operation As CommonCryptoMB.CryptoOperation = CommonCryptoMB.CryptoOperation.Encrypt
        
        // AES
        Dim Algorithm As CommonCryptoMB.CryptoAlgorithm = CommonCryptoMB.CryptoAlgorithm.AES
        
        // CBC mode and padding
        Dim Options As Integer = BitWiseOR(CommonCryptoMB.kCCOptionPKCS7Padding, CommonCryptoMB.kCCOptionCBCMode)
        
        // IV Key
        Dim IV As Xojo.Core.MemoryBlock
        If IVKey <> "" Then 'leave as nil?
          IV = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(IVKey)
        End If
        
        // get data to encrypt as memoryblock
        Dim EncryptedData As Xojo.Core.MemoryBlock = CommonCryptoMB.Crypt(Operation, Algorithm, Options, KeyHash, UnencryptedData, IV)
        
        // append salt and check Hash
        Dim tempMutableMemoryBlock As New Xojo.Core.MutableMemoryBlock(Salt)
        tempMutableMemoryBlock.Append(EncryptedData)
        tempMutableMemoryBlock.Append(CheckHash)
        
        Return CommonCryptoMB.EncodeBase64Memory(New Xojo.Core.MemoryBlock(tempMutableMemoryBlock))
        
      #Else 'macOS, Windows, Linux, desktop, web, console only, but not iOS
        // via MBS Encryption Plugin for Mac/Windows/Linux
        Dim Salt As String = RandomBytesStringMBS(SaltSize)
        Var tempMemoryBlock As MemoryBlock = UnencryptedData.Data 'convert from Xojo.Core.MemoryBlock to MemoryBlock to String
        Dim InputData As String = tempMemoryBlock.StringValue(0, UnencryptedData.Size) 'cannot use TextEncoding.UTF8 as it might be binary data
        tempMemoryBlock = nil 'clear the RAM
        Dim CheckHash As String = SHA512MBS.Hash(InputData)
        
        // get key
        Dim KeyHash As String = SHA256MBS.Hash(PasswordKey)
        
        // encrypt
        Dim ecipher As CipherMBS = CipherMBS.aes_256_cbc
        
        // IV Key
        Dim IV As MemoryBlock
        If IVKey <> "" Then 'leave as nil?
          IV = IVKey
        End If
        
        If ecipher.EncryptInit(KeyHash, IV) Then 'change Nil to IV later!
          ecipher.Padding = True
          Dim EncryptedData As String = ecipher.ProcessString(InputData) + ecipher.FinalizeAsString
          
          Return EncodeBase64MBS(Salt + EncryptedData + CheckHash, 0, "").ToText
          
        Else
          Return ""
        End If
      #EndIf
          
    End Function
    Protected Function Decrypt(EncryptedBase64 As Text, PasswordKey As Text, IVKey As Text, SaltSize As Integer = 8) as Text
      #If TargetiOS Then 'iOS and macOS only
        // don't need to create Salt
        
        // get hash of key
        Dim KeyHash As Xojo.Core.MemoryBlock = HashKey(PasswordKey)
        
        // set to decrypt
        Dim Operation As CommonCryptoMB.CryptoOperation = CommonCryptoMB.CryptoOperation.Decrypt
        
        // AES
        Dim Algorithm As CommonCryptoMB.CryptoAlgorithm = CommonCryptoMB.CryptoAlgorithm.AES
        
        // CBC mode and padding
        Dim Options As Integer = BitWiseOR(CommonCryptoMB.kCCOptionPKCS7Padding, CommonCryptoMB.kCCOptionCBCMode)
        
        // IV Key
        Dim IV As Xojo.Core.MemoryBlock
        If IVKey <> "" Then 'leave as nil?
          IV = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(IVKey)
        End If
        
        // get data to decrypt as memoryblock
        Dim EncryptedData As Xojo.Core.MemoryBlock = CommonCryptoMB.DecodeBase64Memory(EncryptedBase64)
        
        // remove salt and check Hash
        Dim CheckHash As Xojo.Core.MemoryBlock = EncryptedData.Right(64)
        EncryptedData = EncryptedData.Mid(SaltSize, EncryptedData.Size - 64 - SaltSize) 'remove Salt and CheckHash, zero-based so start from character #8
        
        Dim DecryptedData As Xojo.Core.MemoryBlock = CommonCryptoMB.Crypt(Operation, Algorithm, Options, KeyHash, EncryptedData, IV)
        
        If CheckHash <> CommonCryptoMB.Hash(CommonCryptoMB.Hashes.SHA512, DecryptedData) Then 'check that the Hash is still correct ie the text has not been tampered with
          Return ""
        End If
        
        'Return DecryptedData
        Return CommonCryptoMB.EncodeBase64Memory(DecryptedData)
        
      #Else 'macOS, Windows, Linux, desktop, web, console only, but not iOS
        // don't need to create Salt
        
        // get hash of key
        Dim KeyHash As String = SHA256MBS.Hash(PasswordKey)
        
        // get data to decrypt as String
        Dim EncryptedData As String = DecodeBase64MBS(EncryptedBase64)
        
        // remove salt and check Hash
        Dim CheckHash As String = EncryptedData.RightB(64)
        EncryptedData = EncryptedData.MiddleBytes(SaltSize, EncryptedData.LenB - 64 - SaltSize) 'remove Salt and CheckHash, zero-based so start from character #8
        
        // IV Key
        Dim IV As MemoryBlock
        If IVKey <> "" Then 'leave as nil?
          IV = IVKey
        End If
        
        // now decrypt
        Dim dcipher As CipherMBS = CipherMBS.aes_256_CBC
        If dcipher.DecryptInit(KeyHash, IV) Then 'change Nil to IV later!
          dcipher.Padding = True
          
          Dim DecryptedData As String = dcipher.ProcessString(EncryptedData) + dcipher.FinalizeAsString
          
          If CheckHash <> SHA512MBS.Hash(DecryptedData) Then 'check that the Hash is still correct ie the text has not been tampered with
            Return ""
          End If
          
          Return EncodeBase64MBS(DecryptedData, 0, "").ToText 'use Base64 since Xojo.Core.MemoryBlock sometimes gets corrupted
          
        End If
      #EndIf
          
    End Function
  10. Kem T

    Feb 6 Pre-Release Testers, Xojo Pro, XDC Speakers, MVP Connecticut

    On a side note, once iOS has api2, I'll make sure M_Crypto works there too.

or Sign Up to reply!