Im using grpc for java android, im usuing mutual ssl (tls), my server generated 2 certificates for me (server.ca and client.ca) and a private key (key.key), i changed the key from how i got it(basic key encryption to PKCS8) from
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
to:
-----END PRIVATE KEY-----
and used this code to generated my sslcontext with okhttp with grpc.
private static byte[] getBytesFromInputStream(InputStream is) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[0xFFFF];
for (int len = is.read(buffer); len != -1; len = is.read(buffer)) {
os.write(buffer, 0, len);
}
return os.toByteArray();
}
// build a key store from a set of raw certificates
private static KeyStore createKeyStore(Resources resources, int certsId, boolean ca) {
KeyStore ks = null;
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
if (ca) {
ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
InputStream certIS = resources.openRawResource(R.raw.server);
X509Certificate cert = (X509Certificate) cf.generateCertificate(certIS);
ks.setCertificateEntry("ca", cert);
} else {
ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null, null);
InputStream certIS = resources.openRawResource(R.raw.client);
Certificate cert = cf.generateCertificate(certIS);
InputStream privateKeyIS = resources.openRawResource(R.raw.key);
byte[] privateKeyBytes = getBytesFromInputStream(privateKeyIS);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(privateKeyBytes)));
Certificate[] certChain = new Certificate[1];
certChain[0] = cert;
ks.setKeyEntry("client", privateKey, null, certChain);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return ks;
}
public static ManagedChannel build(String host, int port, Resources resources,
@Nullable String serverHostOverride) {
KeyStore ca = createKeyStore(resources, R.array.certs, true);
KeyStore client = createKeyStore(resources, R.array.certs, false);
OkHttpChannelBuilder channelBuilder =
OkHttpChannelBuilder.forAddress(host, port);
if (serverHostOverride != null) {
// Force the hostname to match the cert the server uses.
channelBuilder.overrideAuthority(serverHostOverride);
}
try {
channelBuilder.negotiationType(io.grpc.okhttp.NegotiationType.TLS);
channelBuilder.useTransportSecurity();
channelBuilder.sslSocketFactory(getSslSocketFactory(ca, client));
} catch (Exception e) {
throw new RuntimeException(e);
}
return channelBuilder.build();
}
private static SSLSocketFactory getSslSocketFactory(KeyStore ca, KeyStore client)
throws Exception {
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
String password = "";
kmf.init(client, password.toCharArray());
// initialize trust manager factor from certs keystore
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ca);
// initialize SSL context from trust manager factory
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
// return socket factory from the SSL context
return context.getSocketFactory();
}
public void connectGrpc() throws Exception {
ManagedChannel c = build("MyPc", 5051, this.getResources(), null);
TabletServiceGrpc.TabletServiceBlockingStub bs = TabletServiceGrpc.newBlockingStub(c);
GetName g= GetName.newBuilder().setField(1).build();
GetNameResponse res=bs.getNameByField(g);
Log.e(TAG,res.getCategoryName());
}
and im getting the following errors:
Read error: ssl=0x7890e89c88: Failure in SSL library, usually a protocol error
error:100000d7:SSL routines:OPENSSL_internal:SSL_HANDSHAKE_FAILURE
(third_party/openssl/boringssl/src/ssl/ssl_lib.cc:1017 0x787007e1bb:0x00000000)
io.grpc.StatusRuntimeException: UNAVAILABLE: End of stream or IOException
Is there a problem with me converting my key from PKCS#1 to PKCS#8 ? Or is there something else? I tried changing my code according to the android docs, but it matched it, and should work.
User contributions licensed under CC BY-SA 3.0