I need to be able to encrypt a database file for storage in the clear on the internet. So I made the code below to encrypt and decrypt it using a one-time pad encryption.
The file will grow to be too big for memory to hold it so the code reads the plaintext 1 megabyte at a time, encrypts each byte and saves it one megabyte at a time. My previous code did everything one byte at a time and hammered the hard drive as a result. This is now much faster and much easier on the hard drive.
Here is the code to do so:
The file will grow to be too big for memory to hold it so the code reads the plaintext 1 megabyte at a time, encrypts each byte and saves it one megabyte at a time. My previous code did everything one byte at a time and hammered the hard drive as a result. This is now much faster and much easier on the hard drive.
Here is the code to do so:
One-Time Pad Encrypt/Decrypt:
'==== Process Globals ====
Sub Process_Globals
' No global variables are needed.
Dim xui As XUI
End Sub
Sub AppStart(Form1 As Form, Args() As String)
Form1.Title = "One-Time Pad Addition Mod Encryption Demo"
Form1.Show
' Define file names.
Dim plainTextFile As String = "paypal_transactions.db" ' Input file to be encrypted.
Dim otpFile As String = "random.bin" ' OTP file; must be at least as big as the plaintext. For perfect security, it needs to be truly random numbers.
Dim encryptedFile As String = "paypal_transactions Encrypted.db" ' Output file for encrypted data.
Dim decryptedFile As String = "paypal_transactions Recovered.db" ' Output file for decrypted data.
' Check that OTP file is large enough.
Dim plainFileSize As Long = File.Size("D:\Downloads", plainTextFile)
Dim otpFileSize As Long = File.Size("D:\Downloads", otpFile)
If otpFileSize < plainFileSize Then
xui.MsgboxAsync("Error: One-Time Pad file (" & otpFileSize & " bytes) is smaller than the plaintext file (" & plainFileSize & " bytes).", "PEBKAC Error")
ExitApplication
End If
' Perform encryption.
EncryptFile(plainTextFile, otpFile, encryptedFile)
Log("Encryption completed.")
' Perform decryption.
DecryptFile(encryptedFile, otpFile, decryptedFile)
Log("Decryption completed.")
Form1.Close
End Sub
'----------------------------------------------------------------
' Encrypts a file using addition modulo 256.
' Reads the plaintext and OTP files in 1 MB blocks, encrypts each block,
' and writes the resulting encrypted data in 1 MB blocks.
Sub EncryptFile(inFile As String, otpFile As String, outFile As String)
Dim inRAF As RandomAccessFile
inRAF.Initialize("D:\Downloads", inFile, True)
Dim otpRAF As RandomAccessFile
otpRAF.Initialize("D:\Downloads", otpFile, True)
Dim outRAF As RandomAccessFile
outRAF.Initialize("D:\Downloads", outFile, False)
' Define block size as 1 MB.
Dim BLOCK_SIZE As Int = 1024 * 1024
' Allocate buffers for plaintext, OTP, and encrypted output.
Dim plainBuffer(BLOCK_SIZE) As Byte
Dim otpBuffer(BLOCK_SIZE) As Byte
Dim outBuffer(BLOCK_SIZE) As Byte
Dim totalSize As Long = inRAF.Size
Dim offset As Long = 0
Do While offset < totalSize
' Calculate how many bytes to read for this block.
Dim bytesToRead As Int = Min(BLOCK_SIZE, totalSize - offset)
' Read one block from the plaintext and the OTP file.
inRAF.ReadBytes(plainBuffer, 0, bytesToRead, offset)
otpRAF.ReadBytes(otpBuffer, 0, bytesToRead, offset)
' Process the block: encrypt each byte (addition modulo 256).
For i = 0 To bytesToRead - 1
Dim plainByte As Int = Bit.And(plainBuffer(i), 0xFF)
Dim otpByte As Int = Bit.And(otpBuffer(i), 0xFF)
outBuffer(i) = (plainByte + otpByte) Mod 256
Next
' Write the encrypted block to the output file.
outRAF.WriteBytes(outBuffer, 0, bytesToRead, offset)
offset = offset + bytesToRead
Loop
inRAF.Close
otpRAF.Close
outRAF.Close
End Sub
'----------------------------------------------------------------
' Decrypts a file that was encrypted using addition modulo 256.
' Reads the encrypted and OTP files in 1 MB blocks, decrypts each block,
' and writes the resulting plain text in 1 MB blocks.
Sub DecryptFile(encryptedFile As String, otpFile As String, outFile As String)
Dim inRAF As RandomAccessFile
inRAF.Initialize("D:\Downloads", encryptedFile, True)
Dim otpRAF As RandomAccessFile
otpRAF.Initialize("D:\Downloads", otpFile, True)
Dim outRAF As RandomAccessFile
outRAF.Initialize("D:\Downloads", outFile, False)
' Define block size as 1 MB.
Dim BLOCK_SIZE As Int = 1024 * 1024
' Allocate buffers for encrypted data, OTP, and decrypted output.
Dim encryptedBuffer(BLOCK_SIZE) As Byte
Dim otpBuffer(BLOCK_SIZE) As Byte
Dim outBuffer(BLOCK_SIZE) As Byte
Dim totalSize As Long = inRAF.Size
Dim offset As Long = 0
Do While offset < totalSize
Dim bytesToRead As Int = Min(BLOCK_SIZE, totalSize - offset)
inRAF.ReadBytes(encryptedBuffer, 0, bytesToRead, offset)
otpRAF.ReadBytes(otpBuffer, 0, bytesToRead, offset)
' Process each byte of the block: decrypt using modulo arithmetic.
For i = 0 To bytesToRead - 1
Dim encryptedByte As Int = Bit.And(encryptedBuffer(i), 0xFF)
Dim otpByte As Int = Bit.And(otpBuffer(i), 0xFF)
outBuffer(i) = (encryptedByte - otpByte + 256) Mod 256
Next
' Write the decrypted block to the output file.
outRAF.WriteBytes(outBuffer, 0, bytesToRead, offset)
offset = offset + bytesToRead
Loop
inRAF.Close
otpRAF.Close
outRAF.Close
End Sub
Last edited: