I have been trying to use the Android Keystore in a Kivy app and I have got 90% of the way through but I have got stuck at the last hurdle.
When encrypting, you call javax.crypto.Cipher with an init method which gets autoclassed to JavaMultipleMethod (the init method) by Pyjnius.
input = Cipher/getInstance('RSA/ECB/PKCS1Padding', 'AndroidOpenSSL')
input.init(Cipher.ENCRYPT_MODE, cast('java.security.Key', public_key))
This cast is needed because the signature is for java.security.Key but the public key is an interface (my Java is non-existent so may get things wrong). This works and is a known workaround:
For the decrypt though I get an error:
WARNING:kivy:stderr: jnius.jnius.JavaException: JVM exception occurred: Need RSA private or public key
so I am stuck either way. I tried various things. I couldn't call getMethod on an instance of the autoclassed Cipher for some reason (it was always complaining about the number of arguments whether I passed it multiple arguments, a list of arguments or a Java array) but I could call getMethods and filter to get the right java.lang.reflect.Method. I couldn't then get Method.invoke to work (it claimed Method had no attribute 'invoke') :(
I also tried creating my own Cipher class:
#class Cipher(JavaClass, metaclass=MetaJavaClass):
#__javaclass__ = 'javax/crypto/Cipher'
#ENCRYPT_MODE = JavaStaticField('()I')
#DECRYPT_MODE = JavaStaticField('()I')
#getInstance = JavaMethod('(Ljava/lang/String;Ljava/lang/String;)Ljavax/crypto/Cipher;')
#init = JavaMethod('(ILjava/security/Key;)V')
(PS it would be really useful if the documentation pointed out that __metaclass__ doesn't work on Python3)
but didn't get any further with that - just got 'Unable to find a None method!' errors when calling getInstance for the first time.
Irritatingly this is just about the last of a long series of Java commands to get the Android Keystore working, all of which are working except this one...