Part 1: The key
This is just a write up of my findings regarding the exchange of encrypted data between B4A/B4J and LockBox3 (Delphi). This write up focuses just on LockBox3's implementation of AES (128, 192, and 256 bit) cipher and the block modes ECB and CBC. On the Delphi side, before proceeding to exchange string data with the outside world, the programmer needs to ensure that all string encoding is done via UTF8.
For a quick overview of AES, feel free to read @KMatle's write up (https://www.b4x.com/android/forum/threads/b4x-aes-encryption-lessons-learned-best-practice.97927/).
As mentioned in @KMatle's write up, the key size of AES is either 128, 192, or 256. That translates into password lengths of 16, 24, or 32 bytes. The way that LockBox generates the key is as follows:
1) The password string is converted into bytes, using the appropriate encoding. For our purposes, the encoding needs to be UTF8.
2) If the number of bytes is equal to or greater than the password length required for the appropriate key size, then use the password, truncating it to the proper size if necessary.
3) If the number of bytes is less than the key size, create a SHA1 hash out of the password bytes. This hash is 20 bytes long. If the hash is long enough for the key size in question, use it, truncating it to the proper size. Otherwise, keep concatenating the hash until the proper key size is produced.
Note: The above code (and future code) uses @agraham's ByteConverter library (https://www.b4x.com/android/forum/threads/byteconverter-library.6787/#content).
This is just a write up of my findings regarding the exchange of encrypted data between B4A/B4J and LockBox3 (Delphi). This write up focuses just on LockBox3's implementation of AES (128, 192, and 256 bit) cipher and the block modes ECB and CBC. On the Delphi side, before proceeding to exchange string data with the outside world, the programmer needs to ensure that all string encoding is done via UTF8.
For a quick overview of AES, feel free to read @KMatle's write up (https://www.b4x.com/android/forum/threads/b4x-aes-encryption-lessons-learned-best-practice.97927/).
As mentioned in @KMatle's write up, the key size of AES is either 128, 192, or 256. That translates into password lengths of 16, 24, or 32 bytes. The way that LockBox generates the key is as follows:
1) The password string is converted into bytes, using the appropriate encoding. For our purposes, the encoding needs to be UTF8.
2) If the number of bytes is equal to or greater than the password length required for the appropriate key size, then use the password, truncating it to the proper size if necessary.
3) If the number of bytes is less than the key size, create a SHA1 hash out of the password bytes. This hash is 20 bytes long. If the hash is long enough for the key size in question, use it, truncating it to the proper size. Otherwise, keep concatenating the hash until the proper key size is produced.
B4X:
Private Sub MakeKeyBytes(keySize As Int, password As String) As Byte()
'If the password is keySize / 8 bytes or greater in length, just truncate password to proper byte size
'If password is less than keySize /8 bytes in length, create a SHA1 digest of the password
' (20 bytes), and concatenate the digest and truncate to proper byte size.
Dim bc As ByteConverter
Dim keyBytes(keySize / 8) As Byte
Dim passwordBytes() As Byte = password.GetBytes("UTF8")
If passwordBytes.Length >= keyBytes.Length Then
bc.ArrayCopy(passwordBytes, 0, keyBytes, 0, keyBytes.Length)
Else
Dim md As MessageDigest
Dim hash() As Byte = md.GetMessageDigest(passwordBytes, "SHA1")
Dim offset As Int = 0
Do While offset < keyBytes.Length
If offset + hash.Length < keyBytes.Length Then
bc.ArrayCopy(hash, 0, keyBytes, offset, hash.Length)
Else
bc.ArrayCopy(hash, 0, keyBytes, offset, keyBytes.Length - offset)
End If
offset = offset + hash.Length
Loop
End If
Return keyBytes
End Sub
Note: The above code (and future code) uses @agraham's ByteConverter library (https://www.b4x.com/android/forum/threads/byteconverter-library.6787/#content).