Encrypt and decrypt files

Hi all,

I would like to make a small app where I can write some text, then encrypt it, and store it in a file.
Then close the app, reopen the app, load the file, decrypt it, edit it, and store it again etc…

Can you suggest some basic code for the critical steps for achiving this?

Thanks in advance !

Luciano

What code do you already have?

see
https://documentation.xojo.com/api/cryptography/crypto.html

https://documentation.xojo.com/api/files/binarystream.html

https://documentation.xojo.com/api/user_interface/desktop/savefiledialog.html

https://documentation.xojo.com/api/user_interface/desktop/openfiledialog.html

https://documentation.xojo.com/api/files/specialfolder.html

Thanks for asking Beatrix!!!
Here is the backbone of the code. Let me know if you spot something wrong, or if you would use a completely different approach.
In short, my approach is to use the same ‘key’ and ‘initialization vector’ for encrypting and decrypting the text across opening and re-opening of the app. For this I store the info of ‘key’ and ‘initialization vector’ on separated files, for then re-loding these when I re-open the App.

Thanks again !

//// In the Window Opening event, defining ‘key’ and initialization vector (IV):

Var mb As New MemoryBlock(16)
mb.StringValue(0, 16) = "1234567812345678"
Var s As String  = mb.StringValue(0, 16)
initVector=mb

Var mb2 As New MemoryBlock(16)
mb2.StringValue(0, 16) = "abcdefghabcdefgh"
s  = mb2.StringValue(0, 16)
key=mb2

Of note: ‘key’ and ‘IV’ are properry of type MemoryBlock

//// Exporting info for ‘key’ and initialization vector info, so we can re-use when we restart the APP

// Generate a 16-byte MemoryBlock with random bytes
Var MB As New MemoryBlock(16)
MB= key

// Convert the MemoryBlock into a Base64 encoded string just for our visualization
Var encoded As String = EncodeBase64(MB)
TextFieldFromBinFileAsMB.text = encoded

// Create a FolderItem pointing to your desired file location (e.g., Desktop)
Var file As FolderItem = SpecialFolder.Desktop.Child("MB.bin")

// Create a BinaryStream for writing (True creates/overwrites the file)
Var bs As BinaryStream = BinaryStream.Create(file, True)

// Write the MemoryBlock directly to the file
bs.Write(MB)

// Always close your stream when done
bs.Close

// Doing the same for 'IV'

//// Loading info (from file) for ‘key’ and initialization vector

// Get info from from file 
Var file As FolderItem = SpecialFolder.Desktop.Child("MB.bin")

// Open a BinaryStream in read mode (False for read-only)
Var bs As BinaryStream = BinaryStream.Open(file)

// Read exactly 16 bytes into a new MemoryBlock
Var importedMB As MemoryBlock = bs.Read(16) // newMB will contain the original 16 bytes
key = importedMB // assign the value into the property
// Close the stream when finished
bs.Close

//// Encrypt

Var encrypted As MemoryBlock

Var dataToEncrypt As MemoryBlock = TextAreaOriginal.text

// key and initVector are stored in a property 
//  initVector  is now a property 
encrypted = Crypto.AESEncrypt(key, dataToEncrypt, Crypto.BlockModes.CBC, initVector)
EncryptedText= encrypted // storing this into a property 
// visual in text field
TextAreaEncrypted.text =  DefineEncoding(encrypted, Encodings.UTF8)

//// To export the encrypted text:

Var theTemplatesFileExportedWithEncryption As FolderItem
theTemplatesFileExportedWithEncryption =  New FolderItem("/pathToFile.txt", FolderItem.PathModes.Shell)
// create a binary file with the type of text (defined in the file types dialog)
Var bs As BinaryStream
bs = BinaryStream.Create(theTemplatesFileExportedWithEncryption, True)
// check to see if it was created
If bs <> Nil Then
  //write the contents of the editField
  bs.Write(TextAreaEncrypted.Text.ConvertEncoding(Encodings.UTF8))
  // Or use the property were the encrypted text is stored
  
  // close the binaryStream
  bs.Close
End If

//// To Import encrypted text

Var theTemplatesFile As FolderItem
theTemplatesFile =  New FolderItem("pathToFile.txt", FolderItem.PathModes.Shell)

If theTemplatesFile <> Nil Then
  Try
    Var bs As BinaryStream = BinaryStream.Open(theTemplatesFile, False) ' Open as read-only
    ' read the whole binaryStream
    TextAreaEncrypted.Text = bs.Read(bs.Length, Encodings.UTF8)
  Catch e As IOException
    ' something went wrong when opening the file.  This is where you would handle the error
    ' if appropriate
  End Try
End If

//// To descrypt the imported text

Var decrypted As MemoryBlock
Try
  decrypted = Crypto.AESDecrypt(key, EncryptedText , Crypto.BlockModes.CBC, initVector)
  //TextAreaDecrypted.Text = decrypted
  TextAreaDecrypted.Text = DefineEncoding(decrypted, Encodings.UTF8)
  'MessageBox(decrypted)  // decrypted = "Secret!"
Catch 
  TextAreaDecrypted.Text = "There was an error in pairing Key & IV"
End Try

Thanks Markus, I have already read those, but I am sure I missed something important …
I hope you can spot it in the code I just shared.

Luciano, if you do not need a more than secure encryption, have you considered just saving the file as binaryStream or encoding it as EncodeBase64; then you could just open it reading the binaryStream or deconding the base64.

i would make sure the key file can only create once and not overwritten.
and you need to know what key files was used or you never get your data back.

You could just save your file zipped with a good large and obfuscated password.

It would be both encrypted and smaller. Use a different file extension (not .zip).

https://documentation.xojo.com/api/files/folderitem.html#folderitem-zip

1 Like

Thanks to all. it works now!!!
It was a combination of things. Overwrite on the key files but also a mistake from my side.
But Carlo’s idea it is also something I am looking into.
Ciao
L.