HostnameVerifier 接口的不安全实现 - Android
Unsafe implementation of the HostnameVerifier interface - Android
应用在 Play 商店被拒绝的原因:
Your app(s) are using an unsafe implementation of the HostnameVerifier interface. You can find more information about how to resolve the issue in this Google Help Center article.
大家好,
当我将应用程序上传到 Play 商店时,google Play 控制台出现 HostnameVerifier 问题。我已经尝试了我在 Whosebug 上找到的每一个解决方案,但问题仍然是一样的,即 您的应用程序正在使用 HostnameVerifier 接口的不安全实现。
此外,我已经通过 google documentation 解决了这个问题,但没有成功。有人对此有解决方案吗?感谢您的帮助
下面是我的ServiceGenerator
class
public class ServiceGenerator {
private static final String KEY_AUTH_HEADER = "Authorization";
private Context context;
private Retrofit.Builder builder;
private OkHttpClient.Builder httpClient;
HandshakeCertificates certificates;
ServiceGenerator(Context context) {
this.context = context;
final String dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";
httpClient = new OkHttpClient.Builder();
certificates = new HandshakeCertificates.Builder()
.addTrustedCertificate(AppConstants.SSL_CERTIFICATE_DEMO)
.addTrustedCertificate(AppConstants.SSL_CERTIFICATE_LIVE)
// Uncomment if standard certificates are also required.
.addPlatformTrustedCertificates()
.build();
// Install the all-trusting trust manager
final SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new X509TrustManager[]{certificates.trustManager()}, new java.security.SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
httpClient.sslSocketFactory(sslSocketFactory, certificates.trustManager());
httpClient.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
httpClient.connectTimeout(60, TimeUnit.SECONDS);
httpClient.readTimeout(60, TimeUnit.SECONDS);
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
int cacheSize = 20 * 1024 * 1024; // 20 MB
Cache cache = new Cache(context.getCacheDir(), cacheSize);
logging.level(HttpLoggingInterceptor.Level.BASIC);
httpClient.cache(cache);
httpClient.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
if (Functions.isConnected(context)) {
int maxAge = 60 * 2; // read from cache for 2 minute
return originalResponse.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
}
});
httpClient.addInterceptor(logging);
httpClient.addInterceptor(new HeaderInterceptor());
Gson gson = new GsonBuilder()
.setDateFormat(dateFormat)
.create();
builder = new Retrofit.Builder()
.baseUrl(Apis.HOST);
builder.addConverterFactory(GsonConverterFactory.create(gson));
}
class HeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
String authKey = "authKey";
if (PrefUtils.isUserLoggedIn(context) && PrefUtils.getUserFullProfileDetails(context) != null) {
authKey = PrefUtils.getUserFullProfileDetails(context).getAuthKey();
}
Request newRequest = chain.request().newBuilder()
.addHeader("auth-key", authKey)
.build();
return chain.proceed(newRequest);
}
}
public <S> S createService(Class<S> serviceClass) {
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(serviceClass);
}
}
应用在 Play 商店被拒绝的原因:
Your app(s) are using an unsafe implementation of the HostnameVerifier interface. You can find more information about how to resolve the issue in this Google Help Center article.
大家好,
当我将应用程序上传到 Play 商店时,google Play 控制台出现 HostnameVerifier 问题。我已经尝试了我在 Whosebug 上找到的每一个解决方案,但问题仍然是一样的,即 您的应用程序正在使用 HostnameVerifier 接口的不安全实现。
此外,我已经通过 google documentation 解决了这个问题,但没有成功。有人对此有解决方案吗?感谢您的帮助
下面是我的ServiceGenerator
class
public class ServiceGenerator {
private static final String KEY_AUTH_HEADER = "Authorization";
private Context context;
private Retrofit.Builder builder;
private OkHttpClient.Builder httpClient;
HandshakeCertificates certificates;
ServiceGenerator(Context context) {
this.context = context;
final String dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";
httpClient = new OkHttpClient.Builder();
certificates = new HandshakeCertificates.Builder()
.addTrustedCertificate(AppConstants.SSL_CERTIFICATE_DEMO)
.addTrustedCertificate(AppConstants.SSL_CERTIFICATE_LIVE)
// Uncomment if standard certificates are also required.
.addPlatformTrustedCertificates()
.build();
// Install the all-trusting trust manager
final SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new X509TrustManager[]{certificates.trustManager()}, new java.security.SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
httpClient.sslSocketFactory(sslSocketFactory, certificates.trustManager());
httpClient.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
httpClient.connectTimeout(60, TimeUnit.SECONDS);
httpClient.readTimeout(60, TimeUnit.SECONDS);
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
int cacheSize = 20 * 1024 * 1024; // 20 MB
Cache cache = new Cache(context.getCacheDir(), cacheSize);
logging.level(HttpLoggingInterceptor.Level.BASIC);
httpClient.cache(cache);
httpClient.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
if (Functions.isConnected(context)) {
int maxAge = 60 * 2; // read from cache for 2 minute
return originalResponse.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
}
});
httpClient.addInterceptor(logging);
httpClient.addInterceptor(new HeaderInterceptor());
Gson gson = new GsonBuilder()
.setDateFormat(dateFormat)
.create();
builder = new Retrofit.Builder()
.baseUrl(Apis.HOST);
builder.addConverterFactory(GsonConverterFactory.create(gson));
}
class HeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
String authKey = "authKey";
if (PrefUtils.isUserLoggedIn(context) && PrefUtils.getUserFullProfileDetails(context) != null) {
authKey = PrefUtils.getUserFullProfileDetails(context).getAuthKey();
}
Request newRequest = chain.request().newBuilder()
.addHeader("auth-key", authKey)
.build();
return chain.proceed(newRequest);
}
}
public <S> S createService(Class<S> serviceClass) {
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(serviceClass);
}
}