B4J Tutorial Example of chunk based encryption and decryption

Is there a way to catch this error “java.lang.OutOfMemoryError: Java heap space”?

When the error happens it just seems to close the app.. I don’t want the app to close just display the error to the user.

NOTE: it seems that the size if file being encrypted depends on the computer and how much memory it has..
 

Nokia

Active Member
Licensed User
Longtime User
Such errors are usually not recoverable.
Have you tried to return False from Application_Error?

You can also increase the heap size:
B4X:
#VirtualMachineArgs: -Xms4096m -Xmx4096m

Note that this will only affect the program when it runs from the IDE.

I have not tried the application_error, will try that..

but I did try to increase the heap size.. I didn't know how much you can use.. I'll try that as well..
 

DonManfred

Expert
Licensed User
Longtime User
How are you encrypting the File?

I know that there are java solutions which does encrypting a File in Blocks. I expect the Solution to work with 10TB too.
But it needs some java code which runs async.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Code that encrypts and decrypts large files with chunks:
B4X:
#AdditionalJar: bcprov-jdk15on-150
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private ProgressBar1 As ProgressBar
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("1") 'Load the layout file.
    MainForm.Show
    EncryptFile("C:\Users\H\Downloads\1.7z", "123456")
'    DecryptFile("C:\Users\H\Downloads\1.7z.enc", "123456")
End Sub

Sub EncryptFile (Path As String, Password As String)
    Dim size As Long = File.Size(Path, "")
    Dim rafInput, rafOutput As RandomAccessFile
    rafInput.Initialize(Path, "", True)
    rafOutput.Initialize(Path & ".enc", "", False)
    Dim enc As B4XCipher
    Dim buffer(2024 * 1024) As Byte
    Do While rafInput.CurrentPosition < size
        Dim count As Int = rafInput.ReadBytes(buffer, 0, Min(buffer.Length, size - rafInput.CurrentPosition), rafInput.CurrentPosition)
        Dim b() As Byte
        If count = buffer.Length Then
            b = buffer
        Else
            Dim b(count) As Byte
            Bit.ArrayCopy(buffer, 0, b, 0, count)
        End If
        Dim bb() As Byte = enc.Encrypt(b, Password)
        rafOutput.WriteInt(bb.Length, rafOutput.CurrentPosition)
        rafOutput.WriteBytes(bb, 0, bb.Length, rafOutput.CurrentPosition)
        ProgressBar1.Progress = rafInput.CurrentPosition / size
        Sleep(30)
    Loop
    rafInput.Close
    rafOutput.Close
    fx.Msgbox(MainForm, "Done!", "")
End Sub

Sub DecryptFile (Path As String, Password As String)
    Dim size As Long = File.Size(Path, "")
    Dim rafInput, rafOutput As RandomAccessFile
    rafInput.Initialize(Path, "", True)
    rafOutput.Initialize(Path & ".decrypted", "", False)
    Dim b() As Byte
    Dim enc As B4XCipher
    Do While rafInput.CurrentPosition < size
        Dim blockLength As Int = rafInput.ReadInt(rafInput.CurrentPosition)
        If b.Length <> blockLength Then
            Dim b(blockLength) As Byte
        End If
        rafInput.ReadBytes(b, 0, b.Length, rafInput.CurrentPosition)
        Dim bb() As Byte = enc.Decrypt(b, Password)
        rafOutput.WriteBytes(bb, 0, bb.Length, rafOutput.CurrentPosition)
        ProgressBar1.Progress = rafInput.CurrentPosition / size
        Sleep(30)
    Loop
    rafInput.Close
    rafOutput.Close
    fx.Msgbox(MainForm, "Done!", "")
End Sub

Make it return a ResumableSub if you want to wait for it to complete.
 

Nokia

Active Member
Licensed User
Longtime User
Code that encrypts and decrypts large files with chunks:
B4X:
#AdditionalJar: bcprov-jdk15on-150
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private ProgressBar1 As ProgressBar
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("1") 'Load the layout file.
    MainForm.Show
    EncryptFile("C:\Users\H\Downloads\1.7z", "123456")
'    DecryptFile("C:\Users\H\Downloads\1.7z.enc", "123456")
End Sub

Sub EncryptFile (Path As String, Password As String)
    Dim size As Long = File.Size(Path, "")
    Dim rafInput, rafOutput As RandomAccessFile
    rafInput.Initialize(Path, "", True)
    rafOutput.Initialize(Path & ".enc", "", False)
    Dim enc As B4XCipher
    Dim buffer(2024 * 1024) As Byte
    Do While rafInput.CurrentPosition < size
        Dim count As Int = rafInput.ReadBytes(buffer, 0, Min(buffer.Length, size - rafInput.CurrentPosition), rafInput.CurrentPosition)
        Dim b() As Byte
        If count = buffer.Length Then
            b = buffer
        Else
            Dim b(count) As Byte
            Bit.ArrayCopy(buffer, 0, b, 0, count)
        End If
        Dim bb() As Byte = enc.Encrypt(b, Password)
        rafOutput.WriteInt(bb.Length, rafOutput.CurrentPosition)
        rafOutput.WriteBytes(bb, 0, bb.Length, rafOutput.CurrentPosition)
        ProgressBar1.Progress = rafInput.CurrentPosition / size
        Sleep(30)
    Loop
    rafInput.Close
    rafOutput.Close
    fx.Msgbox(MainForm, "Done!", "")
End Sub

Sub DecryptFile (Path As String, Password As String)
    Dim size As Long = File.Size(Path, "")
    Dim rafInput, rafOutput As RandomAccessFile
    rafInput.Initialize(Path, "", True)
    rafOutput.Initialize(Path & ".decrypted", "", False)
    Dim b() As Byte
    Dim enc As B4XCipher
    Do While rafInput.CurrentPosition < size
        Dim blockLength As Int = rafInput.ReadInt(rafInput.CurrentPosition)
        If b.Length <> blockLength Then
            Dim b(blockLength) As Byte
        End If
        rafInput.ReadBytes(b, 0, b.Length, rafInput.CurrentPosition)
        Dim bb() As Byte = enc.Decrypt(b, Password)
        rafOutput.WriteBytes(bb, 0, bb.Length, rafOutput.CurrentPosition)
        ProgressBar1.Progress = rafInput.CurrentPosition / size
        Sleep(30)
    Loop
    rafInput.Close
    rafOutput.Close
    fx.Msgbox(MainForm, "Done!", "")
End Sub

Make it return a ResumableSub if you want to wait for it to complete.

Erel,

thanks for the code example.. when I created the software didn't know I was going to be encrypting large file.. so I test your code in a new project and it encrypted fine and it seem to decrypt fine.

how ever I notice on the decryption when I would rename the file back to original and took the .Decrypted that I could not delete the file and I had to reboot computer. I kind of brushed it off so I implemented the code in my app and encrypting works fine. but when decrypting the look the loop never stops running. even when the file size is reached.

is this something you noticed or did I cause the problem?

B4X:
                Try

                    Dim size As Long = File.Size(strDirTo, strFileNameTo)
                    
                    Log(size)
                    
                    Dim rafInput, rafOutput As RandomAccessFile
                    rafInput.Initialize(strDirTo, strFileNameTo, True)
                    rafOutput.Initialize(Main.strDecDirLoc, strOldName, False)
                    Dim b() As Byte
                    Dim enc As B4XCipher
                    Do While rafInput.CurrentPosition < size
                        Dim blockLength As Int = rafInput.ReadInt(rafInput.CurrentPosition)
                        If b.Length <> blockLength Then
                            Dim b(blockLength) As Byte
                        End If
                        rafInput.ReadBytes(b, 0, b.Length, rafInput.CurrentPosition)
                        Dim bb() As Byte = enc.Decrypt(b, strKey)
                        rafOutput.WriteBytes(bb, 0, bb.Length, rafOutput.CurrentPosition)
                        'ProgressBar1.Progress = rafInput.CurrentPosition / size
                        'Log(rafInput.CurrentPosition / size)
                        Sleep(30)
                    Loop
                    rafInput.Close
                    rafOutput.Close
    
                Catch
                    rafInput.Close
                    rafOutput.Close
                    
                    r(0) = 5
                    r(1) = LastException.Message
                    r(2) = strFileNameTo
                    CallSub2(oClassCalled,"DecResults", r)
                    Return
                End Try
 

Nokia

Active Member
Licensed User
Longtime User
Code that encrypts and decrypts large files with chunks:
B4X:
#AdditionalJar: bcprov-jdk15on-150
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private ProgressBar1 As ProgressBar
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("1") 'Load the layout file.
    MainForm.Show
    EncryptFile("C:\Users\H\Downloads\1.7z", "123456")
'    DecryptFile("C:\Users\H\Downloads\1.7z.enc", "123456")
End Sub

Sub EncryptFile (Path As String, Password As String)
    Dim size As Long = File.Size(Path, "")
    Dim rafInput, rafOutput As RandomAccessFile
    rafInput.Initialize(Path, "", True)
    rafOutput.Initialize(Path & ".enc", "", False)
    Dim enc As B4XCipher
    Dim buffer(2024 * 1024) As Byte
    Do While rafInput.CurrentPosition < size
        Dim count As Int = rafInput.ReadBytes(buffer, 0, Min(buffer.Length, size - rafInput.CurrentPosition), rafInput.CurrentPosition)
        Dim b() As Byte
        If count = buffer.Length Then
            b = buffer
        Else
            Dim b(count) As Byte
            Bit.ArrayCopy(buffer, 0, b, 0, count)
        End If
        Dim bb() As Byte = enc.Encrypt(b, Password)
        rafOutput.WriteInt(bb.Length, rafOutput.CurrentPosition)
        rafOutput.WriteBytes(bb, 0, bb.Length, rafOutput.CurrentPosition)
        ProgressBar1.Progress = rafInput.CurrentPosition / size
        Sleep(30)
    Loop
    rafInput.Close
    rafOutput.Close
    fx.Msgbox(MainForm, "Done!", "")
End Sub

Sub DecryptFile (Path As String, Password As String)
    Dim size As Long = File.Size(Path, "")
    Dim rafInput, rafOutput As RandomAccessFile
    rafInput.Initialize(Path, "", True)
    rafOutput.Initialize(Path & ".decrypted", "", False)
    Dim b() As Byte
    Dim enc As B4XCipher
    Do While rafInput.CurrentPosition < size
        Dim blockLength As Int = rafInput.ReadInt(rafInput.CurrentPosition)
        If b.Length <> blockLength Then
            Dim b(blockLength) As Byte
        End If
        rafInput.ReadBytes(b, 0, b.Length, rafInput.CurrentPosition)
        Dim bb() As Byte = enc.Decrypt(b, Password)
        rafOutput.WriteBytes(bb, 0, bb.Length, rafOutput.CurrentPosition)
        ProgressBar1.Progress = rafInput.CurrentPosition / size
        Sleep(30)
    Loop
    rafInput.Close
    rafOutput.Close
    fx.Msgbox(MainForm, "Done!", "")
End Sub

Make it return a ResumableSub if you want to wait for it to complete.

neverminded Erel.. found the problem had a timer with wrong name... it's working.. thanks Erel..
 
Top