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