Android Question Encrypt and decrypt data

Addo

Well-Known Member
Licensed User
Longtime User
i got an important data that i used to encrypt/decrypt it in delphi using the following code


B4X:
function encryptstrs(const plain : string): String;
var
FLibrary : TCryptographicLibrary;
FCodec : TCodec;
astr : string;
FEncoding : TEncoding;

begin
  Result:= '';


  FLibrary := TCryptographicLibrary.Create(nil);
  FCodec := TCodec.Create(nil);
  try
    FCodec.CryptoLibrary := FLibrary;
    FCodec.StreamCipherId := 'native.StreamToBlock';
    FCodec.BlockCipherId := 'native.AES-256';
    FCodec.ChainModeId := 'native.ECB';
    FCodec.Password := '156xukn';

    FCodec.EncryptString(plain, astr, FEncoding.UTF8);


  finally
  FreeAndNil(FCodec);
  FreeAndNil(FLibrary);
  end;

Result := astr;

end;


function Decryptstrs(const dectxt : string): String;
var
FLibrary : TCryptographicLibrary;
FCodec : TCodec;
dec : string;
FEncoding : TEncoding;

begin
  Result:= '';


  FLibrary := TCryptographicLibrary.Create(nil);
  FCodec := TCodec.Create(nil);
  try
    FCodec.CryptoLibrary := FLibrary;
    FCodec.StreamCipherId := 'native.StreamToBlock';
    FCodec.BlockCipherId := 'native.AES-256';
    FCodec.ChainModeId := 'native.ECB';
    FCodec.Password := '156xukn';

    FCodec.DecryptString(dec, dectxt, FEncoding.UTF8);


  finally
  FreeAndNil(FCodec);
  FreeAndNil(FLibrary);
  end;

Result := dec;

end;

i am not sure how to decrypt and encrypt using the same encryption property in b4a

i have looked into the forum i have seen encryption library code

B4X:
Sub Encrypt(dataToEncrypt As String ) As String

    Dim kg As KeyGenerator
    Dim c As Cipher
    Dim B64 As Base64
    Dim bconv As ByteConverter

    Dim data(0) As Byte
    Dim iv(0) As Byte
    iv = Array As Byte(211, 5, 233, 24, 55, 166, 7, 88) ' 16 bytes for AES
     
    c.Initialize("DESEDE/CBC/PKCS5Padding")
    c.InitialisationVector = iv
    kg.Initialize("DESEDE")
 
    kg.KeyFromBytes(bconv.StringToBytes("1234567890123456","ASCII"))
    data = bconv.StringToBytes(dataToEncrypt, "ASCII")
    data = c.Encrypt(data, kg.Key, True)

    Return B64.EncodeBtoS(data, 0, data.Length)
 
End Sub

Sub Decrypt(encryptedData As String ) As String

    Dim kg As KeyGenerator
    Dim c As Cipher
    Dim B64 As Base64
    Dim bconv As ByteConverter

    Dim data(0) As Byte
    Dim iv(0) As Byte
    iv = Array As Byte(211, 5, 233, 24, 55, 166, 7, 88) ' 16 bytes for AES
     
    c.Initialize("DESEDE/CBC/PKCS5Padding")
    c.InitialisationVector = iv
    kg.Initialize("DESEDE")
    kg.KeyFromBytes(bconv.StringToBytes("1234567890123456","ASCII"))
 
 
    data = B64.DecodeStoB(encryptedData)
    data = c.Decrypt(data, kg.Key, True)

    Return bconv.StringFromBytes(data, "ASCII")

End Sub

but i am not sure how to adapt it to get it work this is how the encryption looks like that i am trying to decrypt

B4X:
SjGSQBY0xu2JG6sWDL3w+T+/rmY20Z93+vSWUGDRklU=
 
Last edited:

Addo

Well-Known Member
Licensed User
Longtime User
i am still trying to get it work i have tried following

B4X:
Sub Encrypt(dataToEncrypt As String ) As String

   Dim su As StringUtils
   Dim kg As KeyGenerator
   Dim C As Cipher
   Dim md As MessageDigest
   Dim encrypted() As Byte
   Dim cHashkey As String
  
   cHashkey = "156xukn"
  
   If cHashkey.Trim = "" Then Return False
  
   kg.Initialize("AES")
   kg.KeyFromBytes(md.GetMessageDigest(cHashkey.GetBytes("UTF8"), "SHA-1"))
  
  
   C.Initialize("AES/ECB/PKCS5Padding")
   encrypted = C.Encrypt(dataToEncrypt.GetBytes("UTF8"), kg.Key, False)

   Return su.EncodeBase64(encrypted)
 
End Sub

i got java.security.InvalidKeyException: Unsupported key size: 20 bytes
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Upvote 0

Addo

Well-Known Member
Licensed User
Longtime User
this was a test encryption with AES-256 that should be decrypt to

Decrypt this text test

i couldn't decrypt it in b4a sense sha-1 hash always gives error in encrypt/decrypt

its very important to use this encryption sense i have huge number of database records encrypted with this method i will be in trouble if i lost it when i migrate to b4a

have tried to use AES-128 encryption method on delphi side and b4a side but also fail to decrypt the output in b4a
 
Upvote 0

Addo

Well-Known Member
Licensed User
Longtime User
its using SHA-1
B4X:
constructor TSimpleCodec.Create;
begin
FMode := cmUnitialized;
FStreamCipher := nil;
FParameterizedStreamCipher := nil;
FBlockCipher  := nil;
FChainMode    := nil;
FOnProgress   := nil;
FKey := nil;
FEnc := nil;
FDec := nil;
FPasswordHasherObject := TSimpleHash.Create;
Supports( FPasswordHasherObject, IHash, FPasswordHasher);
FPasswordHasher.Hash := TSHA1.Create;
FisUserAborted := False;
FXtextCount := 0;
FOutput := nil;
FBuffer := TMemoryStream.Create;
FSender := self;
FDesalination := TDesalinationWriteStream.Create;
FisSalting := False;
FAsymetricKeySizeInBits := Default_AsymetricKeySizeInBits;
FAsymGenProgressEvent := nil
end;

when i use SHA-1 in

B4X:
 kg.Initialize("AES")
   kg.KeyFromBytes(md.GetMessageDigest(cHashkey.GetBytes("UTF8"), "SHA-1"))


it gives me an exception weather i try to crypt or decryptthe liberary i use in delphi called lockbox3

java.security.InvalidKeyException: Unsupported key size: 20 bytes
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi,
using online tools I was able to go from "Decrypt this text test" to its encoded form and way back, using the settings and steps which follows:

Initial string: Decrypt this text test
Encrypting alg: AES/ECB/156xukn
Resulting IV: c1 61 92 c1 d3 63 b1 48 3a e7 7e 5a f5 db 14 ae

Encrypted text (hex): 016e78e5626126b3050bee790f9453d94acff59fdec8ad0314de2acf67589ba8

Hex2String: nxåba&³îy”SÙJÏõŸÞÈÞ*ÏgX›¨
Base64Encode: AW54w6ViYSbCswULw655D8KUU8OZSsOPw7XCn8Oew4jCrQMUw54qw49nWMKbwqg=

On my way back, I found that String2Hex (online tool) gave me:
16e78e5626126b35bee79f9453d94acff59fdec8ad314de2acf67589ba8
where a few char were represented with just the significant digit (i.e. without a leading zero).
Highlighting those chars and adjusting them to 2-digits representation I ended up with the original encrypted string (in hex).
01 6e78e5626126b3 05 0b ee79 0f 9453d94acff59fdec8ad 03 14de2acf67589ba8

which obviously decoded to the original string.

Tools used:
http://aes.online-domain-tools.com/
https://codebeautify.org/string-hex-converter

Why online tools? Because I hadn't time to fire up my PC and test B4x code..eheh

udg
 
Upvote 0

Addo

Well-Known Member
Licensed User
Longtime User
hello @udg

decrypting

B4X:
AW54w6ViYSbCswULw655D8KUU8OZSsOPw7XCn8Oew4jCrQMUw54qw49nWMKbwqg=

gives an error on delphi side which is not decrypted the base64 decoded looks like this

invalid ciphertext

on b4a it raised same exception with the same out put of the base64 decode

nxåba&³îy”SÙJÏõŸÞÈÞ*ÏgX›¨
 
Last edited:
Upvote 0

udg

Expert
Licensed User
Longtime User
I'm not sure to understand. One problem is that we end up with two distinct Base64 encodings for tha same original plain text.
As said, right now I can't fire my PC so I can't help you tuning your code.
My first step will be to try to replicate in code what I did by on-line tools (hoping not to crashing on your same exception..eheh)
I'll let you know about my findings
 
Upvote 0

Addo

Well-Known Member
Licensed User
Longtime User
ihave tried the following

B4X:
Sub Encrypt(dataToEncrypt As String ) As String

    Dim su As StringUtils
    Dim kg As KeyGenerator
    Dim C As Cipher
    Dim md As MessageDigest
    Dim encrypted() As Byte
    Dim cHashkey As String

   
    cHashkey = "156xukn"
   
   If cHashkey.Trim = "" Then Return False
   
    kg.Initialize("AES")

    kg.KeyFromBytes(md.GetMessageDigest(cHashkey.GetBytes("UTF8"), "SHA-256"))
   
   
    C.Initialize("AES/ECB/PKCS5Padding")
    Try
    encrypted = C.Encrypt(dataToEncrypt.GetBytes("UTF8"), kg.Key, False)
    Catch
    Log("error crypting data")  
       
    End Try

    Return su.EncodeBase64(encrypted)
 
End Sub

this does not raise error on delphi side but it turns empty text

GetMessageDigest only works with md5 and sha-256 other choice raise error
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Cross platform encryption is not simple. This is exactly why B4XEncryption was created.

SHA-1 returns a 160 bit hash. AES expects a key of 128 bits.

This code doesn't throw an error. Cannot say whether it is equivalent to your Delphi code:
B4X:
Sub Encrypt(dataToEncrypt As String ) As String

   Dim su As StringUtils
   Dim kg As KeyGenerator
   Dim C As Cipher
   Dim md As MessageDigest
   Dim encrypted() As Byte
   Dim cHashkey As String
   cHashkey = "156xukn"
   If cHashkey.Trim = "" Then Return False
   kg.Initialize("AES")
   Dim bb As BytesBuilder
   bb.Initialize
   bb.Insert(0, md.GetMessageDigest(cHashkey.GetBytes("UTF8"), "SHA-1"))
   kg.KeyFromBytes(bb.SubArray2(0, 128 / 8))
   C.Initialize("AES/ECB/PKCS5Padding")
   Try
       encrypted = C.Encrypt(dataToEncrypt.GetBytes("UTF8"), kg.Key, False)
   Catch
       Log("error crypting data")
       
   End Try

   Return su.EncodeBase64(encrypted)
End Sub

BytesBuilder: https://www.b4x.com/android/forum/threads/89008/#content
 
Upvote 0

Addo

Well-Known Member
Licensed User
Longtime User
@Erel i have tried b4xencryption

i couldn't decrypt it in Delphi as well

here is the encryption in b4a

B4X:
Sub EncryptText(text As String) As String
    Dim su As StringUtils
    Dim c As B4XCipher
    Dim encrypted() As Byte
    encrypted = c.Encrypt(text.GetBytes("utf8"), "123456")
    Return su.EncodeBase64(encrypted)
End Sub

delphi for decryption gives error

No mapping for the Unicode character exists in the target multi-byte code page.

B4X:
function Decryptstrs(const dectxt : string): String;
var
FLibrary : TCryptographicLibrary;
FCodec : TCodec;
dec : string;
FEncoding : TEncoding;

begin
  Result:= '';


  FLibrary := TCryptographicLibrary.Create(nil);
  FCodec := TCodec.Create(nil);
  try
    FCodec.CryptoLibrary := FLibrary;
    FCodec.StreamCipherId := BlockCipher_ProgId;;
    FCodec.BlockCipherId := 'native.AES-128';
    FCodec.ChainModeId := 'native.CBC';
    FCodec.Password := '123456';

    FCodec.DecryptString(dec, dectxt, TEncoding.UTF8);


  finally
  FreeAndNil(FCodec);
  FreeAndNil(FLibrary);
  end;

Result := dec;

end;
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I'm not an expert in the encryption field at all, so take all this with a grain of salt.

I've tried and tried to get the decryption to work, but did not seem to get anywhere. I always needed to use the "NoPadding" option (AES/ECB/NoPadding) or else it would fail and none of the results came close. I finally tried to take a stab at the encryption routine. The sub I'm including actually matches the first 21 characters of the base64 string that was posted in post #1. No matter what I try, I can't seem to get closer. Please note that I read several posts that mention that LockBox is not really designed to be inter-operable with anything but LockBox. The one thing I'm guessing at is that something is off with the padding. When I encrypt, I have to include the PKCS5Padding option, or the encryption fails. Yet when I include this in the decryption of the Base64 string of post #1, the decryption fails. First clue to this came from a lua-lockbox issue posting (here: https://github.com/somesocks/lua-lockbox/issues/14). I then found the following in the LockBox3 source (https://github.com/TurboPack/LockBo...0/run/cryptography/uTPLb_BlockCipher.pas#L147)
B4X:
TSymetricEncryptionOption = (
    optUseGivenIV, // Use the given IV instead of generating one.
                         // This option is not recommended unless trying to achieve
                         // interoperability with OpenSSL.
    optOpenSSL_CompatibilityMode // Use OpenSSL style of block padding, instead of the normal LockBox style.
                                              // This option is not recommended unless trying to achieve
                                             // interoperability with OpenSSL.
);

Some links:
LockBox3 PHP issues (http://lockbox.seanbdurkin.id.au/tiki-view_forum_thread.php?comments_parentId=363&display=print)
LockBox3 mentioned but not considered for Delphi/PHP coexistence (https://stackoverflow.com/questions/10706320/secure-keypair-encryption-solution-in-delphi-php)
LockBox3 Java/.Net issues (http://lockbox.seanbdurkin.id.au/forumthread61)
LockBox/Java issues (https://plus.google.com/102742838225383913409/posts/KRervCcGRF3)

This (http://lockbox.seanbdurkin.id.au/tiki-view_forum_thread.php?comments_parentId=363&display=print) is one of the LockBox3 posts I used to determine what to do. That post explains the SHA1 hashing. It also led me down a rabbit hole with the UTF-16LE for the password (as seen in the code below). Please note that the code below is full of logging and dead ends, but I just left it in there so that others may see what has been tried and what may still be possible.

The code path right now that gets the first 20 characters correct is using GetBytes("UTF8") on the password string. A 32 byte "key" is created using the SHA1 digest that is appended to itself and then extracting 32 bytes. The Cipher uses "AES/ECB/PKCS5Padding". Using "Decrypt this text test" as data and "156xukn" as password, the Base64 string produces is
SjGSQBY0xu2JG6sWDL3w+VRl0CvJijWrecqaGznEZv0=
vs
SjGSQBY0xu2JG6sWDL3w+T+/rmY20Z93+vSWUGDRklU=
B4X:
Sub EncryptLockBox3AES256(data As String, password As String) As String
   Dim bc As ByteConverter
   Dim passwordBytesAscii() As Byte = password.GetBytes("ASCII")
   Log("passwordBytesAscii len & hex")
   Log(passwordBytesAscii.Length)
   Log(bc.HexFromBytes(passwordBytesAscii))
   Dim passwordBytesUTF8() As Byte = password.GetBytes("UTF8")
   Log("passwordBytesUTF8 len & hex")
   Log(passwordBytesUTF8.Length)
   Log(bc.HexFromBytes(passwordBytesUTF8))
   Dim passwordBytesUTF16() As Byte = password.GetBytes("UTF16")
   Log("passwordBytesUTF16 len & hex")
   Log(passwordBytesUTF16.Length)
   Log(bc.HexFromBytes(passwordBytesUTF16))
   Dim passwordBytesUTF16LE(passwordBytesUTF16.Length - 2) As Byte
   Dim x As Int
   For x = 2 To passwordBytesUTF16.Length-1 Step 2
       passwordBytesUTF16LE(x-2) = passwordBytesUTF16(x+1)
       passwordBytesUTF16LE(x-1) = passwordBytesUTF16(x)
   Next
   Log("passwordBytesUTF16LE len & hex")
   Log(passwordBytesUTF16LE.Length)
   Log(bc.HexFromBytes(passwordBytesUTF16LE))
   Dim keyBytes() As Byte
   Dim bb As BytesBuilder
   bb.Initialize
   'bb.Append(passwordBytesUTF16LE)
   'bb.Append(passwordBytesUTF16)
   bb.Append(passwordBytesUTF8)
   'bb.Append(passwordBytesAscii)
   Dim passwordBytes() As Byte
   passwordBytes = bb.ToArray
   'passwordBytes = bb.SubArray(2)
   Log("passwordBytes len & hex")
   Log(passwordBytes.Length)
   Log(bc.HexFromBytes(passwordBytes))
   bb.Clear
   If(passwordBytes.Length > 31) Then
'   If(passwordBytes.Length > 15) Then
       Log("password is long enough")
       bb.Append(passwordBytes)
       keyBytes = bb.SubArray2(0,32)
'       keyBytes = bb.SubArray2(0,16)
   Else
       Log("password is not long enough and will be hashed")
       Dim md As MessageDigest
       Dim hash() As Byte = md.GetMessageDigest(passwordBytes, "SHA1")
       Log("hash len & hex")
       Log(hash.Length)
       Log(bc.HexFromBytes(hash))
       bb.Append(hash)
       bb.Append(hash)
       keyBytes = bb.SubArray2(0,32)
'       keyBytes = bb.SubArray2(0,16)
   End If
   Log("keyBytes len & hex")
   Log(keyBytes.Length)
   Log(bc.HexFromBytes(keyBytes))
   Dim k As KeyGenerator
   k.Initialize("AES")
   k.KeyFromBytes(keyBytes)
   Log("Key from KeyGenerator")
   Log(bc.HexFromBytes(k.KeyToBytes))
   Dim dataBytes() As Byte = data.GetBytes("UTF8")
   Log("dataBytes len & hex")
   Log(dataBytes.Length)
   Log(bc.HexFromBytes(dataBytes))
   Dim c As Cipher
   c.Initialize("AES/ECB/PKCS5Padding")
   'c.Initialize("AES/ECB/NoPadding")
   Dim encrypted() As Byte = c.Encrypt(dataBytes, k.Key, False)
   Log("encrypted len & hex")
   Log(encrypted.Length)
   Log(bc.HexFromBytes(encrypted))
   Dim su As StringUtils
   Dim encoded As String = su.EncodeBase64(encrypted)
   Log("encoded len & output")
   Log(encoded.Length)
   Log(encoded)
   Return encoded
End Sub
 
Upvote 0

Addo

Well-Known Member
Licensed User
Longtime User
@OliverA Wow i am speechless you have saved my life

i have used this code
B4X:
EncryptLockBox3AES256("Decrypt this text test", "156xukn"

on decryption delphi side it gives

Decrypt this tex
in complete decryption

also i have notices if i change the encryption to anything else

B4X:
EncryptLockBox3AES256("any other shorter or longer than 24 charcters", "156xukn")

it does not decrypted if the string is shorter than 24 chars
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
it does not decrypted if the string is shorter than 24 chars
I think I have figured out the final piece of the puzzle. LockBox3 uses "OnesAndZeroes" padding (links are provided in the code below). I've modified the encryption sub to account for that. I've also created a decryption sub that successfully decrypts your hash string. Please note that both subs are still full of logging. I've left them there so you can test various inputs/outputs and hopefully determine where something went wrong (when it does go wrong). Once you feel comfortable with the code, feel free to remove or comment out all the logging.

Additional libraries used:
Encryption 1.1 (https://www.b4x.com/android/forum/threads/base64-and-encryption-library.6839/)
ByteConverter 1.1 (https://www.b4x.com/android/forum/threads/byteconverter-library.6787/)

Additional module used:
BytesBuilder 1.00 (https://www.b4x.com/android/forum/t...s-working-with-arrays-of-bytes.89008/#content)

Additional build in library used:
StringUtils (B4A)
jStringUtils (B4J)

Note: I did all the testing w/B4J. Both subs are very domain specific (LockBox3 AES256/ECB/OnesAndZeroes cipher with, if necessary, SHA1 digest (duplicated and truncated to 32 bytes) for the key) and were not really designed with flexibility in mind. The Java SDK (and the JRE contained with it) and any other Java JREs need to be updated to handle AES256 (use your favorite search engine for this one).

B4X:
Sub DecryptLockBox3AES256ECB(data As String, password As String) As String
   Dim su As StringUtils
   Dim bc As ByteConverter
   Dim encryptedDataDecoded() As Byte = su.DecodeBase64(data)
   Log("encryptedDataDecoded len and hex")
   Log(encryptedDataDecoded.Length)
   Log(bc.HexFromBytes(encryptedDataDecoded))
   Dim passwordBytes() As Byte = password.GetBytes("UTF8")
   Log("passwordBytes len & hex")
   Log(passwordBytes.Length)
   Log(bc.HexFromBytes(passwordBytes))
   Dim keyBytes() As Byte
   Dim bb As BytesBuilder
   bb.Initialize
   'If the password is 32 bytes or greater in length, just truncuate password to 32 bytes.
   'If password is less than 32 bytes in length, create a SHA1 digest of the password
   ' (20 bytes), duplicate the digest and truncuate to 32 bytes.
   'http://lockbox.seanbdurkin.id.au/tiki-view_forum_thread.php?comments_parentId=363&display=print
   If(passwordBytes.Length > 31) Then
       Log("password is long enough")
       bb.Append(passwordBytes)
       keyBytes = bb.SubArray2(0,32)
   Else
       Log("password is not long enough and will be hashed")
       Dim md As MessageDigest
       Dim hash() As Byte = md.GetMessageDigest(passwordBytes, "SHA1")
       Log("hash len & hex")
       Log(hash.Length)
       Log(bc.HexFromBytes(hash))
       bb.Append(hash)
       bb.Append(hash)
       keyBytes = bb.SubArray2(0,32)
   End If
   Log("keyBytes len & hex")
   Log(keyBytes.Length)
   Log(bc.HexFromBytes(keyBytes))
   Dim k As KeyGenerator
   k.Initialize("AES")
   k.KeyFromBytes(keyBytes)
   'Let's decrypt the data
   Dim c As Cipher
   c.Initialize("AES/ECB/NoPadding")
   Dim decrypted() As Byte = c.decrypt(encryptedDataDecoded, k.Key, False)
   Log("decrypted len & hex")
   Log(decrypted.Length)
   Log(bc.HexFromBytes(decrypted))
   'LockBox3 uses "OneAndZeroes padding"
   'https://github.com/TurboPack/LockBox3/blob/7e7889fbb86becae8f3a7ede7b4a4ca61ef3ef60/run/cryptography/uTPLb_StreamToBlock.pas#L704
   'https://github.com/TurboPack/LockBox3/blob/7e7889fbb86becae8f3a7ede7b4a4ca61ef3ef60/run/cryptography/uTPLb_StreamToBlock.pas#L1013
   'https://www.cryptosys.net/pki/manpki/pki_paddingschemes.html
   'Let's remove any padding
   Dim padIntroducer As Byte = 0x80
   Dim x As Int
   For x = decrypted.Length - 1 To 0 Step -1
       If decrypted(x) = padIntroducer Then Exit
   Next
   Log("padIntroducer location: " & x)
   bb.Clear
   bb.Append(decrypted)
   If x = 0 Then bb.Clear
   If x > 0 Then bb.Remove(x,bb.Length)
   Log("After pad removal (hex)")
   Log(bc.HexFromBytes(bb.ToArray))
   Dim plainText As String = BytesToString(bb.ToArray, 0, bb.Length, "UTF8")
   Return(plainText)
End Sub

Sub EncryptLockBox3AES256ECB(data As String, password As String) As String
   Dim bc As ByteConverter
   'LockBox3 mentions something about UTF-16LE for password, but that did not work
   'UTF-8 seems to do the trick
   'http://lockbox.seanbdurkin.id.au/tiki-view_forum_thread.php?comments_parentId=363&display=print
   Dim passwordBytes() As Byte = password.GetBytes("UTF8")
   Log("passwordBytes len & hex")
   Log(passwordBytes.Length)
   Log(bc.HexFromBytes(passwordBytes))
   Dim keyBytes() As Byte
   Dim bb As BytesBuilder
   bb.Initialize
   'If the password is 32 bytes or greater in length, just truncuate password to 32 bytes.
   'If password is less than 32 bytes in length, create a SHA1 digest of the password
   ' (20 bytes), duplicate the digest and truncuate to 32 bytes.
   'http://lockbox.seanbdurkin.id.au/tiki-view_forum_thread.php?comments_parentId=363&display=print
   If(passwordBytes.Length > 31) Then
       Log("password is long enough")
       bb.Append(passwordBytes)
       keyBytes = bb.SubArray2(0,32)
   Else
       Log("password is not long enough and will be hashed")
       Dim md As MessageDigest
       Dim hash() As Byte = md.GetMessageDigest(passwordBytes, "SHA1")
       Log("hash len & hex")
       Log(hash.Length)
       Log(bc.HexFromBytes(hash))
       bb.Append(hash)
       bb.Append(hash)
       keyBytes = bb.SubArray2(0,32)
   End If
   Log("keyBytes len & hex")
   Log(keyBytes.Length)
   Log(bc.HexFromBytes(keyBytes))
   Dim k As KeyGenerator
   k.Initialize("AES")
   k.KeyFromBytes(keyBytes)
   Dim dataBytes() As Byte = data.GetBytes("UTF8")
   Log("dataBytes len & hex")
   Log(dataBytes.Length)
   Log(bc.HexFromBytes(dataBytes))
   'LockBox3 uses "OneAndZeroes padding"
   'https://github.com/TurboPack/LockBox3/blob/7e7889fbb86becae8f3a7ede7b4a4ca61ef3ef60/run/cryptography/uTPLb_StreamToBlock.pas#L704
   'https://github.com/TurboPack/LockBox3/blob/7e7889fbb86becae8f3a7ede7b4a4ca61ef3ef60/run/cryptography/uTPLb_StreamToBlock.pas#L712
   'Let's add padding
   Dim x As Int = 16 - (dataBytes.Length Mod 16)
   Log("16 - (dataBytes.Length Mod 16) = " & x)
   bb.Clear
   bb.Append(dataBytes)
   bb.Append(Array As Byte (0x80))
   Dim y As Int
   For y = 2 To x
       bb.Append(Array As Byte (0x00))
   Next
   dataBytes = bb.ToArray
   Log("dataBytes after padding len & hex")
   Log(dataBytes.Length)
   Log(bc.HexFromBytes(dataBytes))
   'Encrypt padded data
   Dim c As Cipher
   c.Initialize("AES/ECB/NoPadding")
   Dim encrypted() As Byte = c.Encrypt(dataBytes, k.Key, False)
   Log("encrypted len & hex")
   Log(encrypted.Length)
   Log(bc.HexFromBytes(encrypted))
   'Finally, Base64 the encrypted data
   Dim su As StringUtils
   Dim encoded As String = su.EncodeBase64(encrypted)
   Log("encoded len & output")
   Log(encoded.Length)
   Log(encoded)
   Return encoded
End Sub
 
Upvote 0

Addo

Well-Known Member
Licensed User
Longtime User
@OliverA OMG you have saved my entire life You are a legend Thank you very much for this great help and for the time you have spent into this
this will not only help me as a person it will help Manny others more who moved already i am speechless really Thank you bazillion times
 
Upvote 0

dcoun

Member
Licensed User
Longtime User
This is really helpful for me too.
Trying to encrypt a couple of words, in B4J I am getting:
Waiting for debugger to connect...
Program started.
passwordBytes len & hex
25
38373539383735383437353332373930323832363538373239
password is not long enough and will be hashed
hash len & hex
20
83429111D9E0FF8516687A713B169847DC6674EF
keyBytes len & hex
32
83429111D9E0FF8516687A713B169847DC6674EF83429111D9E0FF8516687A71
dataBytes len & hex
12
6B6A666C6B646A666A6C6764
16 - (dataBytes.Length Mod 16) = 4
dataBytes after padding len & hex
16
6B6A666C6B646A666A6C676480000000
Error occurred on line: 161 (Main)
java.security.InvalidKeyException: Illegal key size or default parameters
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1026)
at javax.crypto.Cipher.implInit(Cipher.java:801)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1249)
at javax.crypto.Cipher.init(Cipher.java:1186)
at anywheresoftware.b4a.agraham.encryption.CipherWrapper.doFinal(CipherWrapper.java:139)
at anywheresoftware.b4a.agraham.encryption.CipherWrapper.Encrypt(CipherWrapper.java:160)
at b4j.example.main._encryptlockbox3aes256ecb(main.java:277)
at b4j.example.main._button1_click(main.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:613)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:228)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
at anywheresoftware.b4a.BA$1.run(BA.java:215)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:748)
It has to do with:
https://stackoverflow.com/questions...ey-size-or-default-parameters/6481658#6481658

I installed the following:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
in ${java.home}/jre/lib/security/
and works OK
 
Last edited:
Upvote 0
Top