Android Question (SOLVED) B4XEncryption difference between B4J and B4A? (or is it me? probably me...)

walt61

Well-Known Member
Licensed User
Longtime User
When I do the following:
- encrypt file X with B4J to new file Y, and
- decrypt file Y with B4A to new file Z, then
- new file Z is not identical to original file X

All other combinations (B4J -> B4J, B4A -> B4A, B4A -> B4J) appear to work correctly.

Environment:
- OS: Win 10 or Linux Mint with Wine (tried both)
- JDK: OpenJDK 19.0.2
- B4A: 13.40; relevant libs: B4XEncryption 1.00, RandomAccessFile 2.33
- B4J: 10.30; relevant libs: jB4XEncryption 1.00, jRandomAccessFile 2.35

Demo project attached and the relevant encryption/decryption methods added below. Any insight would be greatly appreciated!

B4X:
Private Sub EncryptFile(inPath As String, outPath As String, encKey As String) As Boolean

    Dim enc As B4XCipher
    Dim result As Boolean
    Dim rafInput, rafOutput As RandomAccessFile

    TextArea1.Text = TextArea1.Text & CRLF & "Input file to encrypt: " & inPath & CRLF & "Encrypted output file: " & outPath

    If File.Exists(outPath, "") Then File.Delete(outPath, "")

    rafInput.Initialize(inPath, "", True)
    rafOutput.Initialize(outPath, "", False)

    Try
        Dim size As Long = File.Size(inPath, "")
        Dim b(size) As Byte
        rafInput.ReadBytes(b, 0, size, 0)
        Dim bb() As Byte = enc.Encrypt(b, encKey)
        rafOutput.WriteBytes(bb, 0, bb.Length, rafOutput.CurrentPosition)
        result = True
    Catch
        TextArea1.Text = TextArea1.Text & CRLF & LastException
        result = False
    End Try

    rafInput.Close
    rafOutput.Close
    Return result

End Sub

Private Sub DecryptFile(inPath As String, outPath As String, encKey As String) As Boolean

    Dim enc As B4XCipher
    Dim result As Boolean
    Dim rafInput, rafOutput As RandomAccessFile

    TextArea1.Text = TextArea1.Text & CRLF & "Input file to decrypt: " & inPath & CRLF & "Decrypted output file: " & outPath

    If File.Exists(outPath, "") Then File.Delete(outPath, "")

    rafInput.Initialize(inPath, "", True)
    rafOutput.Initialize(outPath, "", False)

    Try
        Dim size As Long = File.Size(inPath, "")
        Dim b(size) As Byte
        rafInput.ReadBytes(b, 0, size, 0)
        Dim bb() As Byte = enc.Decrypt(b, encKey)
        rafOutput.WriteBytes(bb, 0, bb.Length, 0)
        result = True
    Catch
        TextArea1.Text = TextArea1.Text & CRLF & LastException
        result = False
    End Try

    rafInput.Close
    rafOutput.Close

    Return result

End Sub
 

Attachments

  • CryptTest.zip
    12.1 KB · Views: 26
Last edited:
Solution
Found it ! I was using #AdditionalJar: bcprov-jdk18on-177 and that appears to have been the culprit. Just in case someone else runs into this issue:

These ones work fine:
bcprov-jdk15on-154
bcprov-jdk15on-165
bcprov-jdk18on-1.81 (must have had brain fog, this one does not work)

These don't:
bcprov-jdk15to18-177
bcprov-jdk18on-171
bcprov-jdk18on-177
bcprov-jdk18on-1.81

teddybear

Well-Known Member
Licensed User
Try testing using the B4XEncryption in B4J to see if there are any differences
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I'm implemented this task with simpler code:
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    Dim password As String = "123456"
    Dim c As B4XCipher
    Dim original() As Byte = File.ReadBytes(File.DirAssets, "original.dat")
    Log("Original length: " & original.Length)
    #if B4J
    Dim encrypted() As Byte = c.Encrypt(original, password)
    File.WriteBytes(File.DirApp, "encrypted.dat", encrypted) 'copy back to Files folder of B4J and B4A
    #end if
    Dim decrypted() As Byte = c.Decrypt(File.ReadBytes(File.DirAssets, "encrypted.dat"), password)
    Log("Decrypted length: " & decrypted.Length)
    Log("Compare: " & CompareArrays(original, decrypted))
End Sub

Private Sub CompareArrays(b1() As Byte, b2() As Byte) As Boolean
    If b1.Length <> b2.Length Then Return False
    Dim bb1 As B4XBytesBuilder
    bb1.Initialize
    bb1.Append(b1)
    Return bb1.IndexOf(b2) = 0
End Sub

Output in B4A:

Original length: 12438
Decrypted length: 12438
Compare: true
 

Attachments

  • 1.zip
    60 KB · Views: 33
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
With large files, File.ReadBytes into a byte array would surely lead to out of memory errors?
your code
Dim size As Long = File.Size(inPath, "") Dim b(size) As Byte rafInput.ReadBytes(b, 0, size, 0) Dim bb() As Byte = enc.Decrypt(b, encKey)
also load the complete file into memory!?
 
Upvote 0

walt61

Well-Known Member
Licensed User
Longtime User
With the above example code, that's correct, Don. However, what I'm actually using is Erel's code from the link in post 5, which encrypts/decrypts files in chunks. I've reduced it as much as possible to pinpoint the issue.

To elaborate a bit about the project:
- server is a Raspberry Pi with an external USB disc, placed 'offsite' (at a friend's or family member or wherever) and a B4J server program
- clients are B4J or B4A
- all traffic is encrypted
- files (and some metadata like the original file path) are encrypted/decrypted client-side; the server only knows 'there is a file', it doesn't know its real name or what it contains

The intention is to have an offsite backup/sync that would be completely useless for anyone who would steal it/break into it. Safe personal cloud storage, you might say.
 
Upvote 0

walt61

Well-Known Member
Licensed User
Longtime User
Found it ! I was using #AdditionalJar: bcprov-jdk18on-177 and that appears to have been the culprit. Just in case someone else runs into this issue:

These ones work fine:
bcprov-jdk15on-154
bcprov-jdk15on-165
bcprov-jdk18on-1.81 (must have had brain fog, this one does not work)

These don't:
bcprov-jdk15to18-177
bcprov-jdk18on-171
bcprov-jdk18on-177
bcprov-jdk18on-1.81
 
Last edited:
Upvote 1
Solution
Top