B4J Question Cannot merge external library

avalle

Active Member
Licensed 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
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...
 

OliverA

Expert
Licensed 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:

OliverA

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

avalle

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