B4J Question Cannot merge external library

avalle

Active Member
Licensed User
Longtime User
While trying a B4J project using the Bouncy Castle external library https://www.bouncycastle.org/download/bcprov-jdk15on-162.jar I get an error if using #MergeLibraries: True

java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/ECB/ZeroBytePadding

B4X:
'Bouncy Castle Sample app
'Non-UI application (console / server application)
#Region Project Attributes
    #CommandLineArgs:
    #MergeLibraries: False
    #AdditionalJar: bcprov-jdk15on-162
    'External Libraries:
    'Library can be found here: https://www.bouncycastle.org/download/bcprov-jdk15on-162.jar
#End Region
Sub Process_Globals
 
End Sub
Sub AppStart (Args() As String)
    Dim joSecurity As JavaObject
    joSecurity.InitializeStatic("java.security.Security")
#if B4J
    Dim jo As JavaObject
    jo.InitializeNewInstance("org.bouncycastle.jce.provider.BouncyCastleProvider", Null)
    joSecurity.RunMethod("addProvider", Array As Object (jo))
#else if B4A
    ' Seems to just work as of Android 5.1 (oldest version I have)
'    Dim jo As JavaObject
'    jo.InitializeNewInstance("org.spongycastle.jce.provider.BouncyCastleProvider", Null)
'    joSecurity.RunMethod("insertProviderAt", Array As Object (jo, 1))
#else
    Log("ERROR: UNSUPPORTED PLATFORM")
    Return
#End If
 
    Dim hex As String = "33363730424239462F2F312F2F8971C5072144415AEEEE5212B7B13A662F84C59C99E71D68D17F55BF30680DB556E2ADC4C6854877A3C17384C48C132903E66FAA795AD0E3812576F4EC0F5F2C000000"
    Dim hexCurated As String = "8971C5072144415AEEEE5212B7B13A662F84C59C99E71D68D17F55BF30680DB556E2ADC4C6854877A3C17384C48C132903E66FAA795AD0E3812576F4EC0F5F2C"
    'Dim hexCurated As String = "8971C5072144415AEEEE5212B7B13A66"
    Dim bc As ByteConverter
    Dim pktHeader() As Byte = bc.HexToBytes("33363730424239462F2F312F2F")
    Log(bc.StringFromBytes(pktHeader, "ASCII"))
    Dim pktData() As Byte = bc.HexToBytes(hexCurated)
    Log(BytesToString(pktData, 0, pktData.Length, "ASCII"))
    Log(pktData.Length)
    Dim kg As KeyGenerator
    Dim C As Cipher
  
    kg.Initialize("AES")
    kg.KeyFromBytes("0123456789ABCDEF".GetBytes("ASCII"))
    
    C.Initialize("AES/ECB/ZeroBytePadding")
 
    Dim decryptedBytes() As Byte = C.Decrypt(pktData, kg.Key, False)
    Log(bc.HexFromBytes(decryptedBytes))
    Log(bc.StringFromBytes(decryptedBytes, "ASCII"))
 
    Dim textToEncrypt As String = "0000754C//00409D27558D//05.03.10//02.00.44//Hello"
    Dim textBytes() As Byte = textToEncrypt.GetBytes("ASCII")
    Log($"textBytes.Length = ${textBytes.Length}"$)
    Log(bc.HexFromBytes(textBytes))
    Dim textEncryptedBytes() As Byte = C.Encrypt(textBytes, kg.Key, False)
    Log($"textEncryptedBytes.Length = ${textEncryptedBytes.Length}"$)
    Log(bc.HexFromBytes(textEncryptedBytes))
 
    Dim textLength As Int  = textBytes.Length
    Log($"textLength = ${textLength}"$)
    Dim byteBlocks As Int = textLength / 16
    If (textLength Mod 16) > 0 Then byteBlocks = byteBlocks + 1
    Log($"byteBlocks * 16 = ${byteBlocks *16}"$)
    Dim textPadded(byteBlocks * 16) As Byte
    bc.ArrayCopy(textBytes, 0, textPadded, 0, textBytes.Length)
    Log($"textPadded.Length = ${textPadded.Length}"$)
    Log(bc.HexFromBytes(textPadded))
    For x = 0 To byteBlocks - 1
        Dim buffer(16) As Byte
        bc.ArrayCopy(textPadded, x * 16, buffer, 0, 16)
        Dim bufferEncrypted() As Byte = C.Encrypt(buffer, kg.Key, False)
        Log($"bufferEncrypted: ${bc.HexFromBytes(bufferEncrypted)}"$)
    Next
 
End Sub
'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Switching to #MergeLibraries: False works fine with no error.
Any idea why?

Thanks
Andrea
 

avalle

Active Member
Licensed User
Longtime User
Just noticed the following Note from @mindful in https://www.b4x.com/android/forum/threads/sshj-ssh-scp-sftp-for-java.88615

*NOTE2* Also when running in Release you should set #MergeLibraries: False because of the bouncy castle dependency (bcprov-jdk15on-159) which is a signed jar, and when running with #MergeLibraries: True that jar is decompiled and compiled in your jar and therefore losses its signing.

So I tried again and I can run it fine with #MergeLibraries: True when in Debug mode, but I need #MergeLibraries: False when in Release mode.

It's always time to learn something...
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
When I answered here https://www.b4x.com/android/forum/threads/aes128-ecb-decrypt.108828/#post-680970, I indeed used DEBUG mode. But even in Release mode, I'm not having issues with the Bouncy Castle library and MergeLibraries being set to True. Odd... Even odder: https://www.b4x.com/android/forum/t...-cbc-encrypting-decrypting.97962/#post-620970. I had the issue before too and came to the same conclusion (with the same link as source) as you, but now, everything just seems to work. Hm...

B4J: 7.51
Java: Amazon Corretto JDK 1.8.0 212 (64bit)
Java: OpenJDK 11.0.1
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
So does Amazon's and OpenJDK's version of the java compiler just ignore signed files? Or do they handle them differently? Hm...
 
Upvote 0

avalle

Active Member
Licensed User
Longtime User
Amazon Corretto is also based on OpenJDK. So perhaps it handles signed JARs more flexibly than the commercial Oracle JDK.
 
Upvote 0
Top