Pyjnius javax/crypto/Cipher

35 views
Skip to first unread message

Andrew McLeod

unread,
Oct 30, 2018, 7:38:33 AM10/30/18
to Kivy users support
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...

Andrew McLeod

unread,
Oct 30, 2018, 7:42:41 AM10/30/18
to Kivy users support
It is also possible that the workaround worked and the problem is elsewhere...

Andrew McLeod

unread,
Oct 30, 2018, 8:03:42 AM10/30/18
to Kivy users support
Well that's embarrassing - you spend 8 hours trying to fix something, finally give up and ask for help, then realise the workaround did work and it was (then) a different problem (something silly with Android Keystore providers - omitting the 'AndroidOpenSSL' argument to getInstance makes the problem go away).

It would still be good though if a) you could pick your method from a JavaMultipleMethod, and b) the documentation pointed out that '__metaclass__' is not the right way to do it in Python3.
Reply all
Reply to author
Forward
0 new messages