Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading Apple APNs auth key to Java PrivateKey

Problem

I'm having difficulties loading APN's auth key to Java. My understanding is that Java can read PKCS8 encoded private keys but I get an exception.

Exception I get using Bouncy Castle (bcprov-jdk15on-1.55)

org.bouncycastle.jcajce.provider.asymmetric.util.ExtendedInvalidKeySpecException: unable to process key spec: java.io.IOException: algorithm identifier 1.2.840.10045.2.1 in key not recognised
    at org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi.engineGeneratePrivate(Unknown Source)
    at java.security.KeyFactory.generatePrivate(KeyFactory.java:366)
Caused by: java.io.IOException: algorithm identifier 1.2.840.10045.2.1 in key not recognised
    at org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi.generatePrivate(Unknown Source)
    ... 29 more

Exception I get using Java (jdk1.8.0_74)

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: Invalid RSA private key
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217)
    at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
Caused by: java.security.InvalidKeyException: Invalid RSA private key
    at sun.security.rsa.RSAPrivateCrtKeyImpl.parseKeyBits(RSAPrivateCrtKeyImpl.java:206)
    at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:342)
    at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356)
    at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:91)
    at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75)
    at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316)
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213)
    ... 28 more
Caused by: java.io.IOException: Version must be 0
    at sun.security.rsa.RSAPrivateCrtKeyImpl.parseKeyBits(RSAPrivateCrtKeyImpl.java:192)
    ... 34 more

Implementation

I have tried using both Java and bouncycastle provider:

byte[] pkcs8EncodedKey = Base64.getDecoder().decode(APNS_PRIVATE_KEY);
KeyFactory factory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = factory.generatePrivate(new PKCS8EncodedKeySpec(pkcs8EncodedKey));

I've created a sample project: http://tutorialpoint.com

Here is the test key

-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg9eWdXw19hL94+Jx1xjb79Y3Hr9rAaRYaoe4XSv6BnPigCgYIKoZIzj0DAQehRANCAAR9VOiSABvXFHeq/hCMEx63Vq0mYneI2aqQu5sLu5x8DrzUd82BodKoUG3dMPWY9m86dGYAR9xhVUlBDpap9TfH
-----END PRIVATE KEY-----
like image 814
scetix Avatar asked Dec 29 '25 21:12

scetix


1 Answers

Solution

Basically apple does not use RSA algorithm, but rather ECC (Elliptic curve cryptography) so I have to use EC algorithm when loading private key.

http://rahulatjava.blogspot.si/2014/02/elliptical-curve-cryptography-in-java.html

Working version

byte[] pkcs8EncodedKey = Base64.getDecoder().decode(APNS_PRIVATE_KEY);
KeyFactory factory = KeyFactory.getInstance("EC");
PrivateKey privateKey = factory.generatePrivate(new PKCS8EncodedKeySpec(pkcs8EncodedKey));
like image 116
scetix Avatar answered Jan 01 '26 11:01

scetix