接口 X509TrustManager 的不安全实现 - Google 播放
Unsafe implementation of the interface X509TrustManager - Google Play
当我尝试将应用程序上传到 google play 时,我收到一条消息。 “接口 x509trustmanager 的不安全实现”。在来自 Google Play 的消息中说:
To avoid problems when validating the SSL certificate, change the code
of the checkServerTrusted method in the X509TrustManager interface so
that a CertificateException or IllegalArgumentException is thrown when
it detects suspicious certificates.
我发现的所有选项都使用 checkValidity 方法来验证证书,但 Google 还添加了:
Do not use checkValidity to validate the server's certificate. This
method checks the validity of the certificate, not its security.
如何正确更改checkServerTrusted方法的代码?我当前的 x509TrustManager 实现:
X509TrustManager trustManager = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] cArrr = new X509Certificate[0];
return cArrr;
}
@Override
public void checkServerTrusted(final X509Certificate[] chain,
final String authType) throws CertificateException {
try {
chain[0].checkValidity();
} catch (Exception e) {
throw new CertificateException("Certificate not valid or trusted.");
}
}
@Override
public void checkClientTrusted(final X509Certificate[] chain,
final String authType) throws CertificateException {
}
};
我以前遇到过这个错误。就我而言,这是修复它的方法:
private boolean isVerified;
@SuppressLint("TrulyRandom")
public static void handleSSLHandshake() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(final String host, final SSLSession session) {
System.out.print("host" + host+ "\n");
isVerified = host.equalsIgnoreCase(Constants.hostNameVerifierString)
|| host.contains("google") || host.contains("gstatic");
System.out.print(isVerified);
return isVerified;
}
});
} catch (Exception ignored) {
}
}
在有网络调用的activity中可以调用handleSSLHandshake()
方法。或者如果你使用 Dagger 或任何依赖注入库,你应该能够将它注入到你想要创建网络调用的任何地方。
Constants.hostNameVerifierString
是我用于网络调用的 URL,添加了“google”和“gstatic”,因为我也在使用 google 地图.
我以这种方式更改了 X509TrustManager 实现并且应用程序通过了 Google 播放验证:
TrustManager[] victimizedManager = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] myTrustedAnchors = new X509Certificate[0];
return myTrustedAnchors;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if(chain == null || chain.length == 0)throw new IllegalArgumentException("Certificate is null or empty");
if(authType == null || authType.length() == 0) throw new IllegalArgumentException("Authtype is null or empty");
if(!authType.equalsIgnoreCase("ECDHE_RSA") &&
!authType.equalsIgnoreCase("ECDHE_ECDSA") &&
!authType.equalsIgnoreCase("RSA") &&
!authType.equalsIgnoreCase("ECDSA")) throw new CertificateException("Certificate is not trust");
try {
chain[0].checkValidity();
} catch (Exception e) {
throw new CertificateException("Certificate is not valid or trusted");
}
}
}
};
当我尝试将应用程序上传到 google play 时,我收到一条消息。 “接口 x509trustmanager 的不安全实现”。在来自 Google Play 的消息中说:
To avoid problems when validating the SSL certificate, change the code of the checkServerTrusted method in the X509TrustManager interface so that a CertificateException or IllegalArgumentException is thrown when it detects suspicious certificates.
我发现的所有选项都使用 checkValidity 方法来验证证书,但 Google 还添加了:
Do not use checkValidity to validate the server's certificate. This method checks the validity of the certificate, not its security.
如何正确更改checkServerTrusted方法的代码?我当前的 x509TrustManager 实现:
X509TrustManager trustManager = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] cArrr = new X509Certificate[0];
return cArrr;
}
@Override
public void checkServerTrusted(final X509Certificate[] chain,
final String authType) throws CertificateException {
try {
chain[0].checkValidity();
} catch (Exception e) {
throw new CertificateException("Certificate not valid or trusted.");
}
}
@Override
public void checkClientTrusted(final X509Certificate[] chain,
final String authType) throws CertificateException {
}
};
我以前遇到过这个错误。就我而言,这是修复它的方法:
private boolean isVerified;
@SuppressLint("TrulyRandom")
public static void handleSSLHandshake() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(final String host, final SSLSession session) {
System.out.print("host" + host+ "\n");
isVerified = host.equalsIgnoreCase(Constants.hostNameVerifierString)
|| host.contains("google") || host.contains("gstatic");
System.out.print(isVerified);
return isVerified;
}
});
} catch (Exception ignored) {
}
}
在有网络调用的activity中可以调用handleSSLHandshake()
方法。或者如果你使用 Dagger 或任何依赖注入库,你应该能够将它注入到你想要创建网络调用的任何地方。
Constants.hostNameVerifierString
是我用于网络调用的 URL,添加了“google”和“gstatic”,因为我也在使用 google 地图.
我以这种方式更改了 X509TrustManager 实现并且应用程序通过了 Google 播放验证:
TrustManager[] victimizedManager = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] myTrustedAnchors = new X509Certificate[0];
return myTrustedAnchors;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if(chain == null || chain.length == 0)throw new IllegalArgumentException("Certificate is null or empty");
if(authType == null || authType.length() == 0) throw new IllegalArgumentException("Authtype is null or empty");
if(!authType.equalsIgnoreCase("ECDHE_RSA") &&
!authType.equalsIgnoreCase("ECDHE_ECDSA") &&
!authType.equalsIgnoreCase("RSA") &&
!authType.equalsIgnoreCase("ECDSA")) throw new CertificateException("Certificate is not trust");
try {
chain[0].checkValidity();
} catch (Exception e) {
throw new CertificateException("Certificate is not valid or trusted");
}
}
}
};