iOS Question Decryption difference between B4i and B4a

sgt

Member
Licensed User
Hi

I am trying to convert my B4A code to B4i code without an luck. I am reading a encrypted QR Code, basically a json file and the B4A works fine but the B4i does not because the Decrypt2 method returns data that does appear to be decrypted and then the BytesToString method causes an error 'Error decoding data as string'. I see a number of threads talking about the same issue with the only answer being white spaces added to string being decrypted this is not the case here. I see the byte arrays in B4a are Signed array's and the byte array's in B4i are Unsigned. The input, IV and pass method strings are both the same in B4a and B4i versions, length and content. Is there something else I need to do? Any help most appreciated.

B4X:
'B4A Code
Sub AES_Decrypt(input As String, IV As String, pass As String) As String
  
    Dim su As StringUtils
  
    Dim inputB() As Byte = su.DecodeBase64(input)
      
    Dim passB() As Byte = su.DecodeBase64(pass)
    Dim IVb() As Byte = su.DecodeBase64(IV)
 
    Dim kg As KeyGenerator
    Dim C As Cipher
 
    kg.Initialize("AES")
    kg.KeyFromBytes(passB)
 
    C.Initialize("AES/CBC/PKCS5Padding")
    C.InitialisationVector = IVb
  
    Dim datas() As Byte = C.Decrypt(inputB, kg.Key, True)

    ' this result is readable text
    Dim result As String  = BytesToString(datas, 0, datas.Length, "UTF8")

    Return result
  
End Sub

B4X:
'B4I Code

Sub AES_Decrypt(input As String, IV As String, pass As String) As String
  
    Dim su As StringUtils
    'Dim bc As ByteConverter
    Dim inputB() As Byte = su.DecodeBase64(input.Trim)
      
    Dim passB() As Byte = su.DecodeBase64(pass)
    Dim IVb() As Byte = su.DecodeBase64(IV)
 
  
    Dim C As Cipher
  
    Dim keys() As Byte =  C.GenerateKey(passB, "SHA-256", Null, 0)
  
    'C.Initialize("AES/CBC/PKCS5Padding")
    'C.InitialisationVector = IVb
 
    Dim data() As Byte = C.Decrypt2(inputB, keys,"AES", IVb, C.OPTION_PKCS7Padding)
  
 
    Return BytesToString(data, 0, data.Length, "UTF-8")

End Sub
 
Last edited:

sgt

Member
Licensed User
Just to help anyone else out with the same issue the following code work in the end. However the decrypted text had a CRLF on the end which needed to be removed before parsing the json data.
B4X:
Sub AES_Decrypt(input As String) As String
    
    Dim su As StringUtils
    Dim inputB() As Byte = su.DecodeBase64(input)
    Dim keyB() As Byte = su.DecodeBase64(key) '
    Dim IVb() As Byte = su.DecodeBase64(iv)
 
    Dim C As Cipher
    Dim data() As Byte = C.Decrypt2(inputB, keyB, "AES", IVb, 0)
    
    Dim result As String =  BytesToString(data, 0, data.Length, "UTF-8")

    Return result.SubString2(0, result.Length - 2)
    
End Sub
 
Upvote 0

emexes

Expert
Licensed User
the decrypted text had a CRLF on the end
CRLF in B4X is just a single ASCII linefeed character ie Chr(10), eg per IDE popup help:

upload_2019-10-23_12-10-11.png


which needed to be removed
but you are removing two characters, and thus perhaps some defensive programming might be warranted, eg:
B4X:
'remove trailing Chr(10) or Chr(13)&Chr(10) apparently added by decryption process
If result.EndsWith(Chr(10)) Then
    result = result.SubString2(0, result.Length - 1)
    If result.EndsWith(Chr(13)) Then
        result = result.SubString2(0, result.Length -1)
    End If
End If

Even better would be to resolve exactly which part of the process is adding the extra character(s). Perhaps that might give a clue as to how to stop it happening, or at least reveal some plausible reason as to why it happens.

Also, does it happen with both B4A and B4I, or only one of them?
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
It would be really nice if you could provide us an input string (the base 64 encoded encryption output) that can reproduce the issue. Even your solution works for you, if there is an issue with the B4i encryption library, we need to solve that issue in the library, not as a hack
 
Upvote 0

sgt

Member
Licensed User
Hi OliverA
Went back to have a good look at what was happening. The B4A and B4i input strings are exactly the same both have the same content and size. The B4i Decrypt2 method returns a byte array with 2 more bytes than the B4A version. They are not CRLF but 0x02 characters which are Start of Text characters. I can give you the string in a private message as I would have to give you the key as well and this is the clients key.
 
Upvote 0

OliverA

Expert
Licensed User
That looks like the padding bytes of PKCS#5/#7 (https://en.m.wikipedia.org/wiki/Padding_(cryptography)). I’m guessing you are using the same length string to get the 0x02 extras. With different string sizes you should get different padding bytes. Looks like B4i library may not stripping the padding bytes. If you could try some different strings and see if you get different byte endings, that would be great. Are you using the latest library for B4i? The one that fixed the 0 byte padding? It’ll take me a couple of hours before I can write some test code
 
Upvote 0

OliverA

Expert
Licensed User
Just testing the iOS side of things, the only time I get the padding issue is I use
B4X:
Dim datas() As Byte = C.Encrypt2(inputB, key, "AES", IVb, C.OPTION_PKCS7Padding)
to encrypt and
B4X:
Dim data() As Byte = C.Decrypt2(inputB, keys,"AES", IVb, 0)
to decrypt instead of
B4X:
Dim data() As Byte = C.Decrypt2(inputB, keys,"AES", IVb, C.OPTION_PKCS7Padding)
This
B4X:
Dim keys() As Byte =  C.GenerateKey(passB, "SHA-256", Null, 0)
creates a keys bytes array with nothing but zeroes.
This
B4X:
Dim keys() As Byte =  C.GenerateKey(passB, "SHA-256", Null, 1)
produces a key, but it does not generate the same encrypted output as B4J and therefore
B4X:
    kg.Initialize("AES")
    kg.KeyFromBytes(passB)
does not seem to be equivalent to
B4X:
Dim keys() As Byte =  C.GenerateKey(passB, "SHA-256", Null, 0)
nor
B4X:
Dim keys() As Byte =  C.GenerateKey(passB, "SHA-256", Null, 1)
 

Attachments

  • 20191023_B4iCryptIssue.zip
    5.4 KB · Views: 111
Upvote 0
Top