I've implemented an (unfortunate) amount of cross platform cryptographic operations to iOS, however never in Kotlin. Assumed padding was a bugbear on one system. Bad key lengths were another issue with a different system.
I strongly suggest manually copying keys from one system to the other to ensure this isn't key generation issue first off, then, if it's actually an encryption problem, double check you're not double encoding/double decoding data through base64 or something like that. It's not at all surprising when a cryptographic api is like "here, lets also toss in a base64 decode and not document it well".
AES GCM is natively supported in CryptoKit although I understand it will be a bit of an interop pain for you due to the swift package.
https://developer.apple.com/documentation/cryptokit/symmetrickey
I do see your preferred library is specifying SHA1 at one place (the mask generation function). The number of libraries which wholesale pull SHA1 out to make passing security audits go well mean there is a decent chance you're accidentally getting a different mask gen function on iOS. If you're considerably more familiar with the Kotlin/Java side of things, attempting to decrypt things by adjusting your kotlin/backend code first to figure out what parameters iOS keygen is giving you for the key their then figuring out how to fix it is an approach that can work well.
With crossplatform frameworks and the iOS keychain, it's also worth a spot check to verify you're not pulling out something
really weird that isn't a key at all. The c interface to the iOS keychain is full of footguns.