谁能告诉我从文件中提取/转换证书.crt和私钥.key文件的正确方法/命令.pem?我刚读过它们是可以互换的,但不是如何.
我想我需要创建一个新的SSL套接字工厂?此外,出于显而易见的原因,我不想使用全局SSL上下文(https://github.com/square/okhttp/issues/184).
谢谢!
编辑:
从okhttp 2.1.0开始,您可以非常轻松地修复证书.
请参阅此处的源代码以开始使用
WebView对android 的控制,是否支持SSL?
我正在尝试加载一个使用受信任的ssl证书的网页,但WebView它只是白色.
有什么建议?
我正在使用Retrofit来访问我的REST API.但是,当我把我的API放在ssl后面并访问它时,http://myhost/myapi我得到了这个错误:
我的API落后于SSL,我是否需要做一些额外的事情?
这是我如何连接:
private final String API = "https://myhost/myapi";
private final RestAdapter REST_ADAPTER = new RestAdapter.Builder()
.setServer(API)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
01-10 09:49:55.621 2076-2100/com.myapp.mobile D/Retrofit? javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:401)
at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497)
at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)
at retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.java:90)
at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:48)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:287)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:222)
at $Proxy12.signin(Native Method)
at com.myapp.loginactivity$3.doInBackground(LoginActivity.java:143)
at com.myapp.loginactivity$3.doInBackground(LoginActivity.java:136)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841) …Run Code Online (Sandbox Code Playgroud) 我一直在努力让这个工作.我正在尝试使用自签名证书通过https连接到我的服务器.我不认为现在还没有任何页面或示例.
我做了什么:
它用于openssl s_client -connect domain.com:443从服务器获取证书.然后使用充气城堡创建一个bks密钥库.
从原始文件夹中读取创建的密钥库,将其添加到sslfactory,然后再添加到OkHttpClient.像这样:
public ApiService() {
mClient = new OkHttpClient();
mClient.setConnectTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
mClient.setReadTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
mClient.setCache(getCache());
mClient.setCertificatePinner(getPinnedCerts());
mClient.setSslSocketFactory(getSSL());
}
protected SSLSocketFactory getSSL() {
try {
KeyStore trusted = KeyStore.getInstance("BKS");
InputStream in = Beadict.getAppContext().getResources().openRawResource(R.raw.mytruststore);
trusted.load(in, "pwd".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trusted);
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
return sslContext.getSocketFactory();
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
public CertificatePinner getPinnedCerts() {
return new CertificatePinner.Builder()
.add("domain.com", "sha1/theSha=")
.build();
} …Run Code Online (Sandbox Code Playgroud)在Android应用上使用com.squareup.okhttp:okhttp:2.4.0with com.squareup.retrofit:retrofit:1.9.0,尝试通过HTTPS与服务器REST API进行通信,该API使用自签名证书.
服务器密钥库有一个私钥和2个证书,服务器和根证书.openssl s_client输出 -
Certificate chain
0 s:/C=...OU=Dev/CN=example.com
i:/C=... My CA/emailAddress=info@example.com
1 s:/C=... My CA/emailAddress=info@example.com
i:/C=... My CA/emailAddress=info@example.com
Run Code Online (Sandbox Code Playgroud)
在Android应用程序中,OkHttp使用根证书的SHA1签名进行初始化 -
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("example.com", "sha1/5d...3b=")
.build();
OkHttpClient client = new OkHttpClient();
client.setCertificatePinner(certificatePinner);
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://example.com")
.setClient(new OkClient(client))
.build();
Run Code Online (Sandbox Code Playgroud)
但是当尝试发送请求失败时会出现异常 -
retrofit.RetrofitError: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy1.report(Unknown Source)
...
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at …Run Code Online (Sandbox Code Playgroud) 我有一个.p12证书文件,我使用SSL转换器将其转换为.pem证书文件.然后我在我的android代码中使用那个pem证书文件,如下所示:
OkHttpClient okHttpClient = new OkHttpClient();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream instream = context.getResources().openRawResource(R.raw.pem_certificate);
Certificate ca;
ca = cf.generateCertificate(instream);
KeyStore kStore = KeyStore.getInstance(KeyStore.getDefaultType());
kStore.load(null, null);
kStore.setCertificateEntry("ca", ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(kStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());
} catch (CertificateException
| KeyStoreException
| NoSuchAlgorithmException
| IOException
| KeyManagementException e) {
e.printStackTrace();
}
baseURL = endpoint;
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(baseURL)
.setClient(new OkClient(okHttpClient))
.build();
service = restAdapter.create(DishService.class);
Run Code Online (Sandbox Code Playgroud)
但是这段代码不起作用.它在"ca = cf.generateCertificate(instream);"行中失败了.使用CertificateException消息.
对不起我的英语不好.我尝试使用libruary OKhttp,我使用https进行post reqest.现在我有错误,当我尝试发布我的例子时,这是错误:
java.net.UnknownServiceException: Unable to find acceptable protocols. isFallback=false, modes=[ConnectionSpec(cipherSuites=[TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA], tlsVersions=[TLS_1_2], supportsTlsExtensions=true)], supported protocols=[SSLv3, TLSv1]
Run Code Online (Sandbox Code Playgroud)
我尝试修复它,但我不能这样做.我不知道我有什么错误
而且我的代码吼叫:
public class PostOKhttp extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String...ulr) {
Response response = null;
OkHttpClient client = new OkHttpClient();
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,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
.build();
client.setConnectionSpecs(Collections.singletonList(spec));
RequestBody postForm = new FormEncodingBuilder()
.add("name", "name")
.build();
Request request …Run Code Online (Sandbox Code Playgroud) 我已经使用本机 http 库完成了 SSL 证书,但如何进行改造。提前致谢。