Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - converting pkcs12 certificate string to x509 certificate object for bks keystore

I am writing an android app that requires SSL certification for certain web requests. Unlike the options I see online about creating the keystore files using the cert file, I have to make an initial web request that returns the certificate as a string in a json response.

The JSON data is formatted like the following... (note: the following certificate is shortened, the "..." does not exist in an actual response)

"result":{
    "pkcs12": "Ulv6GtdFbjzLeqlkelqwewlq822OrEPdH+zxKUkKGX/eN...9801asds3BCfu52dm7JHzPAOqWKaEwIgymlk="
},

I am decoding this value using Base64.deocode to save it as a byte[]

ssl.setPkcs12( Base64.decode( jsonObject.optString( "pkcs12" ) ) );

Then I am trying to create a X509Certificate using the byte[]

CertificateFactory certFactory = CertificateFactory.getInstance( "X.509" );
InputStream in = new ByteArrayInputStream( ssl.getPkcs12() );
X509Certificate cert = (X509Certificate) certFactory.generateCertificate( in );

My code is failing on the generateCertificate() method with

"java.security.cert.CertificateException: org.apache.harmony.security.asn1.ASN1Exception: ASN.1 Sequence: mandatory value is missing at [4]".

I have spent a great deal of time trying to fix what appears to be a simple problem with no luck at all. Any help would be amazing!

like image 925
calebisstupid Avatar asked Oct 17 '11 21:10

calebisstupid


1 Answers

In case anyone else needs the answer...

I was able to work around this by completely stripping out the BouncyCastle libraries and using a PKCS12 store instead of a BKS. The following snippet is the solution. I no longer had to generate a certificate object, instead I am saving the json certificate string in the preferences, then grabbing it and using it to generate a keystore on the fly. The base64 decoder is not the BouncyCastle decoder, it is a custom standard decoder.

KeyStore keyStore = KeyStore.getInstance( "PKCS12" );
String pkcs12 = UserSession.getCertificate( context );
InputStream sslInputStream = new ByteArrayInputStream( MyBase64Decoder.decode( pkcs12.getBytes() ) );
keyStore.load( sslInputStream, "password".toCharArray() );
like image 139
calebisstupid Avatar answered Oct 16 '22 03:10

calebisstupid