【Android】Lollipop(Api21)より下のgRPC通信でTLS1.2を使う

# gRPC

gRPCはHTTP/2をベースとした通信になっているので、実質SSL/TLS通信が必須となっています。(
しかし、Android4系以下はデフォルトでは現状普及しているTLS1.2に対応していません。

# Error内容

5系以上と同じように通信をすると、以下のエラーが発生します。

* TLSが使えない場合gRPCの通信は失敗するのでStatus CodeはUNAVAILABLEになります。(参: [gRPC Status](https://github.com/grpc/grpc/blob/master/doc/statuscodes.md#status-codes-and-their-use-in-grpc))

```
Caused by: io.grpc.StatusRuntimeException: UNAVAILABLE
```

* 根本的なエラー内容

```
Caused by: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x64f34a60: Failure in SSL library, usually a protocol error
error:14077102:SSL routines:SSL23_GET_SERVER_HELLO:unsupported protocol (external/openssl/ssl/s23_clnt.c:714 0x5d3f1d5c:0x00000000)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:448)
at io.grpc.okhttp.OkHttpProtocolNegotiator.negotiate(OkHttpProtocolNegotiator.java:93)
at io.grpc.okhttp.OkHttpProtocolNegotiator$AndroidNegotiator.negotiate(OkHttpProtocolNegotiator.java:159)
at io.grpc.okhttp.OkHttpTlsUpgrader.upgrade(OkHttpTlsUpgrader.java:63)
at io.grpc.okhttp.OkHttpClientTransport$1.run(OkHttpClientTransport.java:427)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:107)
```

# imported modules

`Security`クラスの`getProviders()`メソッドを使うと端末にinstallされているmoduleのリストがわかります。
Android4.4にデフォルトで入っていたのは以下のmoduleでした。
ここにTLS1.2が入っていない為、gRPCの通信部分でエラーが発生しています。

```
*  AndroidOpenSSL, [Provider AndroidOpenSSL Service SSLContext.SSL com.android.org.conscrypt.OpenSSLContextImpl

*  DRLCertFactory, [Provider DRLCertFactory Service CertificateFactory.X509 org.apache.harmony.security.provider.cert.X509CertFactoryImpl
Aliases [X.509]
Attributes {}]

* BC, [Provider BC Service MessageDigest.MD5 com.android.org.bouncycastle.jcajce.provider.digest.MD5$Digest

*  Crypto, [Provider Crypto Service MessageDigest.SHA-1 org.apache.harmony.security.provider.crypto.SHA1_MessageDigestImpl
Aliases [SHA1, SHA]
Attributes {ImplementedIn=Software}, Provider Crypto Service SecureRandom.SHA1PRNG org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl
Aliases []
Attributes {ImplementedIn=Software}, Provider Crypto Service Signature.SHA1withDSA org.apache.harmony.security.provider.crypto.SHA1withDSA_SignatureImpl
Aliases [SHAwithDSA, DSAwithSHA1, SHA1/DSA, SHA/DSA, SHA-1/DSA, DSA, DSS, OID.1.2.840.10040.4.3, 1.2.840.10040.4.3, 1.3.14.3.2.13, 1.3.14.3.2.27]
Attributes {ImplementedIn=Software}, Provider Crypto Service KeyFactory.DSA org.apache.harmony.security.provider.crypto.DSAKeyFactoryImpl
Aliases [1.3.14.3.2.12, 1.2.840.10040.4.1]
Attributes {ImplementedIn=Software}]

*  HarmonyJSSE, [Provider HarmonyJSSE Service SSLContext.SSL com.android.org.conscrypt.SSLContextImpl
Aliases []
Attributes {}, Provider HarmonyJSSE Service SSLContext.SSLv3 com.android.org.conscrypt.SSLContextImpl
Aliases []
Attributes {}, Provider HarmonyJSSE Service SSLContext.TLS com.android.org.conscrypt.SSLContextImpl
Aliases []
Attributes {}, Provider HarmonyJSSE Service SSLContext.TLSv1 com.android.org.conscrypt.SSLContextImpl
Aliases []
Attributes {}, Provider HarmonyJSSE Service KeyManagerFactory.PKIX com.android.org.conscrypt.KeyManagerFactoryImpl
Aliases [X509]
Attributes {}, Provider HarmonyJSSE Service TrustManagerFactory.PKIX com.android.org.conscrypt.TrustManagerFactoryImpl
Aliases [X509]
Attributes {}, Provider HarmonyJSSE Service KeyStore.AndroidCAStore com.android.org.conscrypt.TrustedCertificateKeyStoreSpi
Aliases []
Attributes {}]

* AndroidKeyStore, [Provider AndroidKeyStore Service KeyStore.AndroidKeyStore android.security.AndroidKeyStore
Aliases []
Attributes {}, Provider AndroidKeyStore Service KeyPairGenerator.RSA android.security.AndroidKeyPairGenerator
Aliases []
Attributes {}]

```

# 解決方法

最初はSSLSocketFactoryをoverrideして自作のSocketFactoryからcreateSocketでTLSv1.2を追加して、OKHTTPのChannelBuilderにsslSocketFactoryを追加しました。  
ServerSideStreaming RPCの場合は動作をしたのですが、Simple RPCの場合は動作しませんでした。

主にやり方は`Google Play Services Dynamic Security Provider`を使う方法と`Security`クラスにprovideする方法の2つがあります。


## Google Play Services Dynamic Security Provider

こちらはGoogle Play Serviceを使います。

### gradle

```groovy
apply plugin: 'android'
...

dependencies {
    compile 'com.google.android.gms:play-services:11.4.2'
}
```

### Code

初期化処理を書きます。
通信するActivityでも良いですが、一度しか行わないのでApplication classが良いと思います。

```kotlin
ProviderInstaller.installIfNeededAsync(this, object : ProviderInstaller.ProviderInstallListener {
    override fun onProviderInstalled() {
    }

    override fun onProviderInstallFailed(errorCode: Int, recoveryIntent: Intent?) {
    }
})
```

Google Play Serviceがinstallされていない場合はInstallFailedになります。

### imported modules

```
* GmsCore_OpenSSL, [Provider GmsCore_OpenSSL Service SSLContext.SSL com.google.android.gms.org.conscrypt.OpenSSLContextImpl$TLSv12
Aliases []
Attributes {}, Provider GmsCore_OpenSSL Service SSLContext.TLS com.google.android.gms.org.conscrypt.OpenSSLContextImpl$TLSv12
Aliases []
Attributes {}, Provider GmsCore_OpenSSL Service SSLContext.TLSv1 com.google.android.gms.org.conscrypt.OpenSSLContextImpl$TLSv1
Aliases []
Attributes {}, Provider GmsCore_OpenSSL Service SSLContext.TLSv1.1 com.google.android.gms.org.conscrypt.OpenSSLContextImpl$TLSv11
Aliases []
Attributes {}, Provider GmsCore_OpenSSL Service SSLContext.TLSv1.2 com.google.android.gms.org.conscrypt.OpenSSLContextImpl$TLSv12
Aliases []
Attributes {}, Provider GmsCore_OpenSSL Service SSLContext.Default com.google.android.gms.org.conscrypt.DefaultSSLContextImpl
Aliases []
Attributes {}, Provider GmsCore_OpenSSL Service MessageDigest.SHA-1 com.google.android.gms.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
Aliases [SHA1, SHA, 1.3.14.3.2.26]
Attributes {}, Provider GmsCore_OpenSSL Service MessageDigest.SHA-224 com.google.android.gms.org.conscrypt.OpenSSLMessageDigestJDK$SHA224
Aliases [SHA224, 2.16.840.1.101.3.4.2.4]
Attributes {}, Provider GmsCore_OpenSSL Service MessageDigest.SHA-256 com.google.android.gms.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
Aliases [SHA256, 2.16.840.1.101.3.4.2.1]
Attributes {}, Provider GmsCore_OpenSSL Service MessageDigest.SHA-384 com.google.android.gms.org.conscrypt.OpenSSLMessageDigestJDK$SHA384
Aliases [SHA384, 2.16.840.1.101.3.4.2.2]
Attributes {}, Provider GmsCore_OpenSSL Service MessageDigest.SHA-512 com.google.android.gms.org.conscrypt.OpenSSLMessageDigestJDK$SHA512
Aliases [SHA512, 2.16.840.1.101.3.4.2.3]
Attributes {}, Provider GmsCore_OpenSSL Service MessageDigest.MD5 com.google.android.gms.org.conscrypt.OpenSSLMessageDigestJDK$MD5
Aliases [1.2.840.113549.2.5]
Attributes {}, Provider GmsCore_OpenSSL Service KeyPairGenerator.RSA com.google.android.gms.org.conscrypt.OpenSSLRSAKeyPairGenerator
Aliases [1.2.840.113549.1.1.1, 1.2.840.113549.1.1.7, 2.5.8.1.1]
Attributes {}, Provider GmsCore_OpenSSL Service KeyPairGenerator.EC com.google.android.gms.org.conscrypt.OpenSSLECKeyPairGenerator
Aliases [1.2.840.10045.2.1, 1.3.133.16.840.63.0.2]
Attributes {}, Provider GmsCore_OpenSSL Service KeyFactory.RSA com.google.android.gms.org.conscrypt.OpenSSLRSAKeyFactory
Aliases [1.2.840.113549.1.1.1, 1.2.840.113549.1.1.7, 2.5.8.1.1]
Attributes {}, Provider GmsCore_OpenSSL Service KeyFactory.EC com.google.android.gms.org.conscrypt.OpenSSLECKeyFactory
Aliases [1.2.840.10045.2.1, 1.3.133.16.840.63.0.2]
Attributes {}, Provider GmsCore_OpenSSL Service KeyAgreement.ECDH com.google.android.gms.org.conscrypt.OpenSSLECDHKeyAgreement
Aliases []
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.ECPrivateKey, SupportedKeyFormats=PKCS#8}, Provider GmsCore_OpenSSL Service Signature.MD5WithRSA com.google.android.gms.org.conscrypt.OpenSSLSignature$MD5RSA
Aliases [MD5WithRSAEncryption, MD5/RSA, 1.2.840.113549.1.1.4, OID.1.2.840.113549.1.1.4, 1.2.840.113549.2.5with1.2.840.113549.1.1.1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA1WithRSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA1RSA
Aliases [SHA1WithRSAEncryption, SHA1/RSA, SHA-1/RSA, 1.2.840.113549.1.1.5, OID.1.2.840.113549.1.1.5, 1.3.14.3.2.26with1.2.840.113549.1.1.1, 1.3.14.3.2.26with1.2.840.113549.1.1.5, 1.3.14.3.2.29, OID.1.3.14.3.2.29]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA224WithRSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA224RSA
Aliases [SHA224WithRSAEncryption, SHA224/RSA, 1.2.840.113549.1.1.14, OID.1.2.840.113549.1.1.14, 2.16.840.1.101.3.4.2.4with1.2.840.113549.1.1.1, 2.16.840.1.101.3.4.2.4with1.2.840.113549.1.1.14]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA256WithRSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA256RSA
Aliases [SHA256WithRSAEncryption, SHA256/RSA, 1.2.840.113549.1.1.11, OID.1.2.840.113549.1.1.11, 2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.1, 2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.11]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA384WithRSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA384RSA
Aliases [SHA384WithRSAEncryption, SHA384/RSA, 1.2.840.113549.1.1.12, OID.1.2.840.113549.1.1.12, 2.16.840.1.101.3.4.2.2with1.2.840.113549.1.1.1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA512WithRSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA512RSA
Aliases [SHA512WithRSAEncryption, SHA512/RSA, 1.2.840.113549.1.1.13, OID.1.2.840.113549.1.1.13, 2.16.840.1.101.3.4.2.3with1.2.840.113549.1.1.1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.NONEwithRSA com.google.android.gms.org.conscrypt.OpenSSLSignatureRawRSA
Aliases []
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLRSAPrivateKey|java.security.interfaces.RSAPrivateKey|com.google.android.gms.org.conscrypt.OpenSSLRSAPublicKey|java.security.interfaces.RSAPublicKey}, Provider GmsCore_OpenSSL Service Signature.SHA1withECDSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA1ECDSA
Aliases [ECDSA, ECDSAwithSHA1, 1.2.840.10045.4.1, 1.3.14.3.2.26with1.2.840.10045.2.1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA224withECDSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA224ECDSA
Aliases [SHA224/ECDSA, 1.2.840.10045.4.3.1, OID.1.2.840.10045.4.3.1, 2.16.840.1.101.3.4.2.4with1.2.840.10045.2.1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA256withECDSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA256ECDSA
Aliases [SHA256/ECDSA, 1.2.840.10045.4.3.2, OID.1.2.840.10045.4.3.2, 2.16.840.1.101.3.4.2.1with1.2.840.10045.2.1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA384withECDSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA384ECDSA
Aliases [SHA384/ECDSA, 1.2.840.10045.4.3.3, OID.1.2.840.10045.4.3.3, 2.16.840.1.101.3.4.2.2with1.2.840.10045.2.1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA512withECDSA com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA512ECDSA
Aliases [SHA512/ECDSA, 1.2.840.10045.4.3.4, OID.1.2.840.10045.4.3.4, 2.16.840.1.101.3.4.2.3with1.2.840.10045.2.1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA1withRSA/PSS com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA1RSAPSS
Aliases [SHA1withRSAandMGF1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA224withRSA/PSS com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA224RSAPSS
Aliases [SHA224withRSAandMGF1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA256withRSA/PSS com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA256RSAPSS
Aliases [SHA256withRSAandMGF1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA384withRSA/PSS com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA384RSAPSS
Aliases [SHA384withRSAandMGF1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service Signature.SHA512withRSA/PSS com.google.android.gms.org.conscrypt.OpenSSLSignature$SHA512RSAPSS
Aliases [SHA512withRSAandMGF1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder|java.security.interfaces.RSAPrivateKey|java.security.interfaces.ECPrivateKey|java.security.interfaces.RSAPublicKey, SupportedKeyFormats=PKCS#8|X.509}, Provider GmsCore_OpenSSL Service SecureRandom.SHA1PRNG com.google.android.gms.org.conscrypt.OpenSSLRandom
Aliases []
Attributes {ImplementedIn=Software}, Provider GmsCore_OpenSSL Service Cipher.RSA/ECB/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipherRSA$Raw
Aliases [RSA/None/NoPadding]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLRSAPrivateKey|java.security.interfaces.RSAPrivateKey|com.google.android.gms.org.conscrypt.OpenSSLRSAPublicKey|java.security.interfaces.RSAPublicKey}, Provider GmsCore_OpenSSL Service Cipher.RSA/ECB/PKCS1Padding com.google.android.gms.org.conscrypt.OpenSSLCipherRSA$PKCS1
Aliases [RSA/None/PKCS1Padding]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLRSAPrivateKey|java.security.interfaces.RSAPrivateKey|com.google.android.gms.org.conscrypt.OpenSSLRSAPublicKey|java.security.interfaces.RSAPublicKey}, Provider GmsCore_OpenSSL Service Cipher.RSA/ECB/OAEPPadding com.google.android.gms.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA1
Aliases [RSA/None/OAEPPadding]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLRSAPrivateKey|java.security.interfaces.RSAPrivateKey|com.google.android.gms.org.conscrypt.OpenSSLRSAPublicKey|java.security.interfaces.RSAPublicKey}, Provider GmsCore_OpenSSL Service Cipher.RSA/ECB/OAEPWithSHA-1AndMGF1Padding com.google.android.gms.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA1
Aliases [RSA/None/OAEPWithSHA-1AndMGF1Padding]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLRSAPrivateKey|java.security.interfaces.RSAPrivateKey|com.google.android.gms.org.conscrypt.OpenSSLRSAPublicKey|java.security.interfaces.RSAPublicKey}, Provider GmsCore_OpenSSL Service Cipher.RSA/ECB/OAEPWithSHA-224AndMGF1Padding com.google.android.gms.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA224
Aliases [RSA/None/OAEPWithSHA-224AndMGF1Padding]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLRSAPrivateKey|java.security.interfaces.RSAPrivateKey|com.google.android.gms.org.conscrypt.OpenSSLRSAPublicKey|java.security.interfaces.RSAPublicKey}, Provider GmsCore_OpenSSL Service Cipher.RSA/ECB/OAEPWithSHA-256AndMGF1Padding com.google.android.gms.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA256
Aliases [RSA/None/OAEPWithSHA-256AndMGF1Padding]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLRSAPrivateKey|java.security.interfaces.RSAPrivateKey|com.google.android.gms.org.conscrypt.OpenSSLRSAPublicKey|java.security.interfaces.RSAPublicKey}, Provider GmsCore_OpenSSL Service Cipher.RSA/ECB/OAEPWithSHA-384AndMGF1Padding com.google.android.gms.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA384
Aliases [RSA/None/OAEPWithSHA-384AndMGF1Padding]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLRSAPrivateKey|java.security.interfaces.RSAPrivateKey|com.google.android.gms.org.conscrypt.OpenSSLRSAPublicKey|java.security.interfaces.RSAPublicKey}, Provider GmsCore_OpenSSL Service Cipher.RSA/ECB/OAEPWithSHA-512AndMGF1Padding com.google.android.gms.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA512
Aliases [RSA/None/OAEPWithSHA-512AndMGF1Padding]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLRSAPrivateKey|java.security.interfaces.RSAPrivateKey|com.google.android.gms.org.conscrypt.OpenSSLRSAPublicKey|java.security.interfaces.RSAPublicKey}, Provider GmsCore_OpenSSL Service Cipher.AES/ECB/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES$ECB$NoPadding
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES/ECB/PKCS5Padding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES$ECB$PKCS5Padding
Aliases [AES/ECB/PKCS7Padding]
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES/CBC/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES$CBC$NoPadding
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES/CBC/PKCS5Padding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES$CBC$PKCS5Padding
Aliases [AES/CBC/PKCS7Padding]
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES/CTR/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES$CTR
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_128/ECB/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_128$ECB$NoPadding
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_128/ECB/PKCS5Padding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_128$ECB$PKCS5Padding
Aliases [AES_128/ECB/PKCS7Padding]
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_128/CBC/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_128$CBC$NoPadding
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_128/CBC/PKCS5Padding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_128$CBC$PKCS5Padding
Aliases [AES_128/CBC/PKCS7Padding, PBEWithHmacSHA1AndAES_128, PBEWithHmacSHA224AndAES_128, PBEWithHmacSHA256AndAES_128, PBEWithHmacSHA384AndAES_128, PBEWithHmacSHA512AndAES_128]
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_256/ECB/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_256$ECB$NoPadding
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_256/ECB/PKCS5Padding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_256$ECB$PKCS5Padding
Aliases [AES_256/ECB/PKCS7Padding]
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_256/CBC/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_256$CBC$NoPadding
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_256/CBC/PKCS5Padding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$AES_256$CBC$PKCS5Padding
Aliases [AES_256/CBC/PKCS7Padding, PBEWithHmacSHA1AndAES_256, PBEWithHmacSHA224AndAES_256, PBEWithHmacSHA256AndAES_256, PBEWithHmacSHA384AndAES_256, PBEWithHmacSHA512AndAES_256]
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.DESEDE/CBC/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$DESEDE$CBC$NoPadding
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.DESEDE/CBC/PKCS5Padding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$DESEDE$CBC$PKCS5Padding
Aliases [DESEDE/CBC/PKCS7Padding]
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.ARC4 com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_CIPHER$ARC4
Aliases [ARCFOUR, RC4, 1.2.840.113549.3.4, OID.1.2.840.113549.3.4]
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES/GCM/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_AEAD$AES$GCM
Aliases [GCM, 2.16.840.1.101.3.4.1.6, 2.16.840.1.101.3.4.1.26, 2.16.840.1.101.3.4.1.46]
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_128/GCM/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_AEAD$AES$GCM$AES_128
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Cipher.AES_256/GCM/NoPadding com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_AEAD$AES$GCM$AES_256
Aliases []
Attributes {SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Mac.HmacMD5 com.google.android.gms.org.conscrypt.OpenSSLMac$HmacMD5
Aliases [1.3.6.1.5.5.8.1.1, HMAC-MD5, HMAC/MD5]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder, SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Mac.HmacSHA1 com.google.android.gms.org.conscrypt.OpenSSLMac$HmacSHA1
Aliases [1.2.840.113549.2.7, 1.3.6.1.5.5.8.1.2, HMAC-SHA1, HMAC/SHA1]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder, SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Mac.HmacSHA224 com.google.android.gms.org.conscrypt.OpenSSLMac$HmacSHA224
Aliases [1.2.840.113549.2.8, HMAC-SHA224, HMAC/SHA224, PBEWITHHMACSHA224]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder, SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Mac.HmacSHA256 com.google.android.gms.org.conscrypt.OpenSSLMac$HmacSHA256
Aliases [1.2.840.113549.2.9, 2.16.840.1.101.3.4.2.1, HMAC-SHA256, HMAC/SHA256, PBEWITHHMACSHA256]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder, SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Mac.HmacSHA384 com.google.android.gms.org.conscrypt.OpenSSLMac$HmacSHA384
Aliases [1.2.840.113549.2.10, HMAC-SHA384, HMAC/SHA384, PBEWITHHMACSHA384]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder, SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service Mac.HmacSHA512 com.google.android.gms.org.conscrypt.OpenSSLMac$HmacSHA512
Aliases [1.2.840.113549.2.11, HMAC-SHA512, HMAC/SHA512, PBEWITHHMACSHA512]
Attributes {SupportedKeyClasses=com.google.android.gms.org.conscrypt.OpenSSLKeyHolder, SupportedKeyFormats=RAW}, Provider GmsCore_OpenSSL Service CertificateFactory.X509 com.google.android.gms.org.conscrypt.OpenSSLX509CertificateFactory
Aliases [X.509]
Attributes {}]

....

```

多すぎるので省略しました。まだあと3倍以上あります。
`GmsCore_OpenSSL`が入っているのがポイントです。`GmsCore_OpenSSL`により、TLS1.2が有効になりました。
これによって、4系でもTLS1.2でgRP通信が行えます。

## Conscypt

GooglePlayServiceはmoduleがたくさんimportされてしまいました。
そこで、必要な分のみimportするため、AndroidとOpenJDK用にTLSを提供しているgoogleの[Conscypt](https://github.com/google/conscrypt)を使用します。



### gradle

```groovy
compile "org.conscrypt:conscrypt-android:1.0.0.RC11"
```
(1.1.0-SNAPSHOTは使えませんでした)

### Code

上記同様一度だけ初期化処理を書きます。
こちらは、TLS1.2に必要な `GmsCore_OpenSSL` のみimportします。

```kotlin
Security.insertProviderAt(Conscrypt.newProvider("GmsCore_OpenSSL"), 1)
```

### imported module

```
* GmsCore_OpenSSL, [Provider GmsCore_OpenSSL Service SSLContext.SSL org.conscrypt.OpenSSLContextImpl$TLSv12
* AndroidOpenSSL, [Provider AndroidOpenSSL Service SSLContext.SSL com.android.org.conscrypt.OpenSSLContextImpl
* DRLCertFactory, [Provider DRLCertFactory Service CertificateFactory.X509 org.apache.harmony.security.provider.cert.X509CertFactoryImpl
Aliases [X.509]
Attributes {}]
* BC, [Provider BC Service MessageDigest.MD5 com.android.org.bouncycastle.jcajce.provider.digest.MD5$Digest
* Crypto, [Provider Crypto Service MessageDigest.SHA-1 org.apache.harmony.security.provider.crypto.SHA1_MessageDigestImpl
Aliases [SHA1, SHA]
Attributes {ImplementedIn=Software}, Provider Crypto Service SecureRandom.SHA1PRNG org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl
Aliases []
Attributes {ImplementedIn=Software}, Provider Crypto Service Signature.SHA1withDSA org.apache.harmony.security.provider.crypto.SHA1withDSA_SignatureImpl
Aliases [SHAwithDSA, DSAwithSHA1, SHA1/DSA, SHA/DSA, SHA-1/DSA, DSA, DSS, OID.1.2.840.10040.4.3, 1.2.840.10040.4.3, 1.3.14.3.2.13, 1.3.14.3.2.27]
Attributes {ImplementedIn=Software}, Provider Crypto Service KeyFactory.DSA org.apache.harmony.security.provider.crypto.DSAKeyFactoryImpl
Aliases [1.3.14.3.2.12, 1.2.840.10040.4.1]
Attributes {ImplementedIn=Software}]
* HarmonyJSSE, [Provider HarmonyJSSE Service SSLContext.SSL com.android.org.conscrypt.SSLContextImpl
Aliases []
Attributes {}, Provider HarmonyJSSE Service SSLContext.SSLv3 com.android.org.conscrypt.SSLContextImpl
Aliases []
Attributes {}, Provider HarmonyJSSE Service SSLContext.TLS com.android.org.conscrypt.SSLContextImpl
Aliases []
Attributes {}, Provider HarmonyJSSE Service SSLContext.TLSv1 com.android.org.conscrypt.SSLContextImpl
Aliases []
Attributes {}, Provider HarmonyJSSE Service KeyManagerFactory.PKIX com.android.org.conscrypt.KeyManagerFactoryImpl
Aliases [X509]
Attributes {}, Provider HarmonyJSSE Service TrustManagerFactory.PKIX com.android.org.conscrypt.TrustManagerFactoryImpl
Aliases [X509]
Attributes {}, Provider HarmonyJSSE Service KeyStore.AndroidCAStore com.android.org.conscrypt.TrustedCertificateKeyStoreSpi
Aliases []
Attributes {}]
* AndroidKeyStore, [Provider AndroidKeyStore Service KeyStore.AndroidKeyStore android.security.AndroidKeyStore
Aliases []
Attributes {}, Provider AndroidKeyStore Service KeyPairGenerator.RSA android.security.AndroidKeyPairGenerator
Aliases []
Attributes {}]
```

こちらは、先ほどとは異なり、defaultに `GmsCore_OpenSSL`部分のみが追加されました。
これによって、4系でもTLS1.2でgRP通信が行えます。

# Conclusion

Conscryptを導入すると、依存関係が増えるので一長一短ですが、各プロジェクトに適した導入方法をとると良いと思います。