Java 与“;找不到证书路径的信任锚。”;

Java 与“;找不到证书路径的信任锚。”;,java,android,spring,retrofit2,okhttp,Java,Android,Spring,Retrofit2,Okhttp,你好,我没有找到解决问题的方法。在新的OkHttp和改型中有一些功能: HandshakeCertificates certificates = new HandshakeCertificates.Builder() .addPlatformTrustedCertificates() .addInsecureHost("192.168.0.150")

你好,我没有找到解决问题的方法。在新的OkHttp和改型中有一些功能:

 HandshakeCertificates certificates =  new HandshakeCertificates.Builder()
                        .addPlatformTrustedCertificates()
                        .addInsecureHost("192.168.0.150")
                        .build();
我正在尝试将我的Android应用程序连接到Spring Boot服务器。此服务器必须使用HTTPS-这不是我的想法。 在这个服务器上,我生成了自签名证书,但仍然有错误,现在我没有任何想法。下面是一个完整的错误:
java.security.cert.CertificateException:java.security.cert.CertPathValidator异常:找不到证书路径的信任锚。
下面我插入改装发电机的代码:

public class ServiceGenerator {
    public static final String API_BASE_URL = "https://192.168.0.150:8443/";
    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    // private static OkHttpClient httpClient = getUnsafeOkHttpClient();

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    private static Retrofit retrofit = builder.build();

    public static <S> S createService(Class<S> serviceClass) {
        return createService(serviceClass, null);
    }

    static public <S> S createService(
            Class<S> serviceClass, final String authToken) {
        if (!TextUtils.isEmpty(authToken)) {
            AuthenticationInterceptor interceptor =
                    new AuthenticationInterceptor(authToken);

            if (!httpClient.interceptors().contains(interceptor)) {
                httpClient.addInterceptor(interceptor);

                HandshakeCertificates certificates =  new HandshakeCertificates.Builder()
                        .addPlatformTrustedCertificates()
                        .addInsecureHost("192.168.0.150")
                        .build();
                httpClient.sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager());

                OkHttpClient okHttpClient = httpClient.build();

                builder.client(okHttpClient);
                retrofit = builder.build();
            }
        }

        return retrofit.create(serviceClass);
    }
}
公共类服务生成器{
公共静态最终字符串API_BASE_URL=”https://192.168.0.150:8443/";
私有静态OkHttpClient.Builder httpClient=new OkHttpClient.Builder();
//私有静态OkHttpClient httpClient=getUnsafeOkHttpClient();
私人静态改装=
新的改型.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
私有静态改装改装=builder.build();
公共静态S createService(类serviceClass){
返回createService(serviceClass,null);
}
静态公共服务(
类serviceClass,最终字符串authToken){
如果(!TextUtils.isEmpty(authToken)){
身份验证侦听器拦截器=
新的AuthenticationInterceptor(authToken);
如果(!httpClient.interceptors().包含(拦截器)){
httpClient.addInterceptor(拦截器);
HandshakeCertificates certificates=新的HandshakeCertificates.Builder()
.addPlatformTrustedCertificates()
.addInsecureHost(“192.168.0.150”)
.build();
httpClient.sslSocketFactory(certificates.sslSocketFactory(),certificates.trustManager());
OkHttpClient OkHttpClient=httpClient.build();
建造商客户(okHttpClient);
改装=builder.build();
}
}
返回改装。创建(serviceClass);
}
}
请求代码:

 private void doLoginRequest() {
        DeviceAPI deviceAPI = ServiceGenerator.createService(DeviceAPI.class);
        Call<JWTResponse> call = deviceAPI.login(new Login(usernameEditText.getText().toString(), passwordEditText.getText().toString()));
        call.enqueue(new Callback<JWTResponse>() {
            @Override
            public void onResponse(Call<JWTResponse> call, Response<JWTResponse> response) {
                if (response.isSuccessful()) {
                    Toast.makeText(LoginActivity.this, response.body().toString(), Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(LoginActivity.this, response.message(), Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<JWTResponse> call, Throwable t) {
                System.out.println(t.getCause());
                Toast.makeText(LoginActivity.this, t.getMessage() , Toast.LENGTH_SHORT).show();
            }
        });
    }
private void doLoginRequest(){
DeviceAPI DeviceAPI=ServiceGenerator.createService(DeviceAPI.class);
Call Call=deviceAPI.login(新登录名(usernameEditText.getText().toString(),passwordEditText.getText().toString());
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
if(response.issusccessful()){
Toast.makeText(LoginActivity.this,response.body().toString(),Toast.LENGTH_SHORT).show();
}否则{
Toast.makeText(LoginActivity.this,response.message(),Toast.LENGTH_SHORT.show();
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
System.out.println(t.getCause());
Toast.makeText(LoginActivity.this,t.getMessage(),Toast.LENGTH_SHORT.show();
}
});
}
Api代码:

public interface DeviceAPI {
    @POST("api/auth/signin")
    Call<JWTResponse> login(@Body Login login);
}

公共接口设备API{
@POST(“api/auth/SIGN”)
调用登录(@Body-login-login);
}

如果您需要更多信息,请给我反馈

此示例显示两次连接到主机-一次使用有效的HTTPS握手,另一次使用addInsecureHost。n、 b.你不会在第二次握手中得到对等方,因为握手不会产生有效的证书

如果在dev服务器上运行,同样的情况也会发生,因此请编辑示例以使用devserver


首先,okhttpclient的配置应该是独立的(不应该在if条件下完成)。如果您的服务器使用SSL(应该始终如此),您应该验证证书。您可以直接添加服务器证书(公钥)(请参阅)。整个改造配置应该在类的构造函数中完成。我猜authtoken总是相同的还是空的?拦截器包含检查也不需要,如果您在Constructor中执行此操作,或者在服务器端有JWT令牌,我尝试添加到android应用程序通用公钥-但仍然没有更改-仍然是相同的错误,提示:最好的方法是使用根证书或中间证书进行验证(它们不会很快过期=您不需要经常更新客户端中的证书文件),例如stackoverflow-这对其他人帮助您并不是很有用。您应该提取一个运行依赖性最小的工作示例。这主要是您提供的示例中的猜测工作。嗨,谢谢您的回答,但是当我尝试将我的IP地址提供给这个示例时,仍然会出现握手错误。
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.tls.HandshakeCertificates.Builder

fun main() {
  val request = Request.Builder()
      .url("https://httpbin.org/get")
      .build()

  var client = OkHttpClient();
  var response = client.newCall(request).execute()

  println(response.handshake?.peerPrincipal) // CN=httpbin.org
  println(response.code)

  val certificates = Builder()
      .addInsecureHost("httpbin.org")
      .build()

  client = OkHttpClient.Builder().sslSocketFactory(certificates.sslSocketFactory(),
      certificates.trustManager
  ).build();
  response = client.newCall(request).execute()

  println(response.handshake?.peerPrincipal) // null
  println(response.code)
}