Android Activer TLSv1.2
J'utilise OKHttp pour mon projet. je veux activer TLSv1.2 pour mon appel de service. tout organisme peut me dire comment faire pour l'activer.
5 réponses
autant que je sache, OKHttp n'inclut pas ses propres bibliothèques SSL/TLS, donc il utilise juste le standard SSLSocket fourni par Android.
ce que les versions TLS sont supportées (et activées) dépend de la version Android utilisée.
Sur certains téléphones TLS 1.2 est supporté mais pas activé par défaut. Dans de tels cas, vous pouvez l'activer en implémentant un wrapper SSLSocketFactory personnalisé qui utilise en interne le SSLSocketFactory par défaut et les appels setEnabledProtocols(new String{"TLS1.2"})
sur chaque Socket créé.
voir Okhttp's HTTPS documentation.
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
.build();
OkHttpClient client = ...
client.setConnectionSpecs(Collections.singletonList(spec));
Vérifiez Mon Code!!Travail parfait!
private void checkTls() {
if (android.os.Build.VERSION.SDK_INT < 21) {
try {
ProviderInstaller.installIfNeededAsync(this, new ProviderInstaller.ProviderInstallListener() {
@Override
public void onProviderInstalled() {
}
@Override
public void onProviderInstallFailed(int i, Intent intent) {
}
});
} catch (Exception e) {
finish();
e.printStackTrace();
}
}
}
public class TLSSocketFactoryCompat extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactoryCompat() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
internalSSLSocketFactory = context.getSocketFactory();
}
public TLSSocketFactoryCompat(TrustManager[] tm) throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tm, new java.security.SecureRandom());
internalSSLSocketFactory = context.getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
//Create list of supported protocols
ArrayList<String> supportedProtocols = new ArrayList<>();
for (String protocol : ((SSLSocket)socket).getEnabledProtocols()) {
//Log.d("TLSSocketFactory", "Supported protocol:" + protocol);
//Only add TLS protocols (don't want ot support older SSL versions)
if (protocol.toUpperCase().contains("TLS")) {
supportedProtocols.add(protocol);
}
}
//Force add TLSv1.1 and 1.2 if not already added
if (!supportedProtocols.contains("TLSv1.1")) {
supportedProtocols.add("TLSv1.1");
}
if (!supportedProtocols.contains("TLSv1.2")) {
supportedProtocols.add("TLSv1.2");
}
String[] protocolArray = supportedProtocols.toArray(new String[supportedProtocols.size()]);
/*for (int i = 0; i < protocolArray.length; i++) {
Log.d("TLSSocketFactory", "protocolArray[" + i + "]" + protocolArray[i]);
}*/
//enable protocols in our list
((SSLSocket)socket).setEnabledProtocols(protocolArray);
}
return socket;
}
}
Utilisation:
OkHttpClient httpClient = new OkHttpClient();
//Add Custom SSL Socket Factory which adds TLS 1.1 and 1.2 support for Android 4.1-4.4
try {
httpClient.setSslSocketFactory(new TLSSocketFactoryCompat());
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
C'est essentiellement la même que la réponse mais je pense qu'un exemple de code serait utile pour quiconque atterrit ici et n'est pas à la hauteur pour naviguer dans le paysage java ssl.
ce qui a finalement fonctionné pour moi était basé sur la question rapportée ici:https://github.com/mattleibow/square-bindings/issues/1
à partir de ce résumé https://gist.github.com/mattleibow/c8abfa323db094b820cc
notez que ces exemples de code sont en C# / Xamarin mais peuvent être traduits en java assez facilement.
internal class CompleteSSLSocketFactory : SSLSocketFactory
{
private readonly SSLSocketFactory innerFactory;
public CompleteSSLSocketFactory (SSLSocketFactory innerFactory)
{
this.innerFactory = innerFactory;
}
public override string[] GetDefaultCipherSuites ()
{
return innerFactory.GetDefaultCipherSuites ();
}
public override string[] GetSupportedCipherSuites ()
{
return innerFactory.GetSupportedCipherSuites ();
}
public override Socket CreateSocket ()
{
return MakeSocketSafe (innerFactory.CreateSocket ());
}
public override Socket CreateSocket (Socket s, string host, int port, bool autoClose)
{
return MakeSocketSafe (innerFactory.CreateSocket (s, host, port, autoClose));
}
public override Socket CreateSocket (string host, int port)
{
return MakeSocketSafe (innerFactory.CreateSocket (host, port));
}
public override Socket CreateSocket (string host, int port, InetAddress localHost, int localPort)
{
return MakeSocketSafe (innerFactory.CreateSocket (host, port, localHost, localPort));
}
public override Socket CreateSocket (InetAddress host, int port)
{
return MakeSocketSafe (innerFactory.CreateSocket (host, port));
}
public override Socket CreateSocket (InetAddress address, int port, InetAddress localAddress, int localPort)
{
return MakeSocketSafe (innerFactory.CreateSocket (address, port, localAddress, localPort));
}
private Socket MakeSocketSafe (Socket socket)
{
var sslSocket = socket as SSLSocket;
if (sslSocket != null) {
// enable all supported protocols for this socket
sslSocket.SetEnabledProtocols (sslSocket.GetSupportedProtocols ());
sslSocket.SetEnabledCipherSuites (sslSocket.GetSupportedCipherSuites ());
}
return socket;
}
}
Et puis de l'appeler comme ceci:
// this.client is an OkHttpClient
if (Android.OS.Build.VERSION.SdkInt < BuildVersionCodes.Lollipop) {
this.client.SetSslSocketFactory(new CompleteSSLSocketFactory(HttpsURLConnection.DefaultSSLSocketFactory));
}
cela a fonctionné pour moi, testé sur API 19.