Chr*_*pix 156 ssl android ssl-certificate
我正在尝试连接到运行godaddy 256位SSL证书的IIS6盒子,我收到错误:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Run Code Online (Sandbox Code Playgroud)
一直试图确定可能导致这种情况的原因,但现在正在绘制空白.
这是我如何连接:
HttpsURLConnection conn;
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream());
Run Code Online (Sandbox Code Playgroud)
Ste*_*vie 203
相反,接受的答案,你并不需要一个定制信任管理器,你需要修复服务器配置!
我在连接到安装了错误的dynadot/alphassl证书的Apache服务器时遇到了同样的问题.我正在使用HttpsUrlConnection(Java/Android)连接,它正在投掷 -
javax.net.ssl.SSLHandshakeException:
java.security.cert.CertPathValidatorException:
Trust anchor for certification path not found.
Run Code Online (Sandbox Code Playgroud)
实际问题是服务器配置错误 - 使用http://www.digicert.com/help/或类似方法对其进行测试,它甚至会告诉您解决方案:
"证书未由受信任的机构签名(检查Mozilla的根存储区).如果您从受信任的机构购买证书,您可能只需安装一个或多个中级证书.请联系您的证书提供商以获取帮助服务器平台."
您还可以使用openssl检查证书:
openssl s_client -debug -connect www.thedomaintocheck.com:443
你可能会看到:
Verify return code: 21 (unable to verify the first certificate)
并且,在输出的早期:
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`
Run Code Online (Sandbox Code Playgroud)
证书链只包含1个元素(您的证书):
Certificate chain
0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
i:/O=AlphaSSL/CN=AlphaSSL CA - G2
Run Code Online (Sandbox Code Playgroud)
...但是应该将链中的签名机构引回到受Android(Verisign,GlobalSign等)信任的链中:
Certificate chain
0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
i:/O=AlphaSSL/CN=AlphaSSL CA - G2
1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
Run Code Online (Sandbox Code Playgroud)
用于配置服务器的说明(和中间证书)通常由颁发证书的机构提供,例如:http://www.alphassl.com/support/install-root-certificate.html
安装我的证书颁发者提供的中间证书后,我现在使用HttpsUrlConnection进行连接时没有错误.
Mat*_*s B 71
@Chrispix的解决方案很危险!信任所有证书允许任何人在中间攻击中做一个人!只需将任何证书发送给客户端即可接受!
将您的证书添加到自定义信任管理器,如本文所述:使用HttpClient通过HTTPS信任所有证书
虽然使用自定义证书建立安全连接有点复杂,但它会为您带来所需的ssl加密安全性,而不会受到中间人攻击的危险!
kli*_*mat 16
您可以在运行时信任特定证书.
只需从服务器下载它,放入资源并使用ssl-utils-android加载:
OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());
Run Code Online (Sandbox Code Playgroud)
在我上面使用的示例中,OkHttpClient
但SSLContext
可以与Java中的任何客户端一起使用.
如果您有任何问题随时问.我是这个小型图书馆的作者.
use*_*104 12
根据最新的Android文档更新(2017年3月):
当您遇到此类错误时:
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:374)
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.getInputStream(HttpURLConnectionImpl.java:177)
at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
Run Code Online (Sandbox Code Playgroud)
问题可能是以下之一:
解决方案是教导HttpsURLConnection
信任一组特定的CA. 怎么样?请查看https://developer.android.com/training/articles/security-ssl.html#CommonProblems
谁正在使用其他AsyncHTTPClient
的com.loopj.android:android-async-http
库,请检查设置AsyncHttpClient使用HTTPS.
回复很老的帖子.但也许它会帮助一些新手,如果没有上述工作.
说明:我知道没有人想解释废话; 而是解决方案.但在一个班轮中,您尝试从本地计算机访问服务到不信任您的计算机的远程计算机.您请求需要从远程服务器获得信任.
解决方案:以下解决方案假定您满足以下条件
脚步:
您需要一个.keystore扩展名文件来注册您的应用.如果你不知道如何创建.keystore文件; 然后按照以下部分创建.keystore文件或以其他方式跳到下一节Sign Apk File
创建.keystore文件
打开Android Studio.单击顶部菜单构建>生成签名APK.在下一个窗口中,单击" 创建新..."按钮.在新窗口中,请输入所有字段的数据.请记住,我推荐的两个密码字段应该具有相同的密码; 不要使用不同的密码; 并且还记住最顶层字段密钥存储路径的保存路径:.输入所有字段后,单击"确定"按钮.
签署Apk文件
现在,您需要使用刚创建的.keystore文件构建已签名的应用程序.跟着这些步骤
Choose existing...
按钮Key store password
和Key password
字段.也输入别名build.gradle
文件中的设置可能会有所不同,您需要选择Build Types
和Flavors
.Build Types
选择release
从下拉菜单中对于Flavors
然而,将取决于在你的设置build.gradle
文件.staging
从这个字段中选择.我使用了以下设置build.gradle
,您可以使用与我相同的设置,但请确保更改applicationId
为您的包名称
productFlavors {
staging {
applicationId "com.yourapplication.package"
manifestPlaceholders = [icon: "@drawable/ic_launcher"]
buildConfigField "boolean", "CATALYST_DEBUG", "true"
buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "true"
}
production {
buildConfigField "boolean", "CATALYST_DEBUG", "false"
buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "false"
}
}
Run Code Online (Sandbox Code Playgroud)单击底部的两个Signature Versions
复选框,然后单击Finish
按钮.
差不多了:
所有的辛勤工作都已完成,现在是真理的运动.要访问由代理备份的Staging服务器,您需要在真正的Android设备测试中进行一些设置.
Android设备中的代理设置:
Modify network
Advanced options
如果您看不到该Proxy Hostname
字段,请单击Proxy Hostname
输入要连接的主机IP或名称.典型的临时服务器将命名为stg.api.mygoodcompany.com
9502
Save
按钮最后一站:
请记住,我们在Sign APK文件部分生成了已签名的apk文件.现在是安装该APK文件的时候了.
adb install
name of the apk file
adb command not found
.输入完整路径C:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe
install
name of the apk file
我希望问题可以解决.如果没有,请给我留言.
萨拉姆!
我在尝试使用使用自签名证书来公开其测试版本的外部 Web 服务时遇到了同样的问题。以下是我用于全局解决该问题的步骤(它将应用您使用的任何框架:Retrofit、oKhttp、HttpUrlConnection)
padlock symbol
在 url 附近,然后details
选择export
格式der
)res/raw/dev_thedomain_private.der
resources/xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">dev.thedomain.private</domain>
<trust-anchors>
<certificates src="@raw/dev_thedomain_private"/>
</trust-anchors>
</domain-config>
</network-security-config>
Run Code Online (Sandbox Code Playgroud)
<application
android:networkSecurityConfig="@xml/network_security_config"
Run Code Online (Sandbox Code Playgroud)
你完成了 !该证书现在将被信任...
如果使用改造,则需要自定义OkHttpClient。
Run Code Online (Sandbox Code Playgroud)retrofit = new Retrofit.Builder() .baseUrl(ApplicationData.FINAL_URL) .client(getUnsafeOkHttpClient().build()) .addConverterFactory(GsonConverterFactory.create()) .build();
完整代码如下。
public class RestAdapter {
private static Retrofit retrofit = null;
private static ApiInterface apiInterface;
public static OkHttpClient.Builder getUnsafeOkHttpClient() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
return builder;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static ApiInterface getApiClient() {
if (apiInterface == null) {
try {
retrofit = new Retrofit.Builder()
.baseUrl(ApplicationData.FINAL_URL)
.client(getUnsafeOkHttpClient().build())
.addConverterFactory(GsonConverterFactory.create())
.build();
} catch (Exception e) {
e.printStackTrace();
}
apiInterface = retrofit.create(ApiInterface.class);
}
return apiInterface;
}
}
Run Code Online (Sandbox Code Playgroud)
使用https://www.ssllabs.com/ssltest/测试域。
Shihab Uddin在 Kotlin 中的解决方案。
import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.*
import javax.security.cert.CertificateException
object {
val okHttpClient: OkHttpClient
val gson: Gson
val retrofit: Retrofit
init {
okHttpClient = getOkHttpBuilder()
// Other parameters like connectTimeout(15, TimeUnit.SECONDS)
.build()
gson = GsonBuilder().setLenient().create()
retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}
fun getOkHttpBuilder(): OkHttpClient.Builder =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
OkHttpClient().newBuilder()
} else {
// Workaround for the error "Caused by: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: Certificate expired at".
getUnsafeOkHttpClient()
}
private fun getUnsafeOkHttpClient(): OkHttpClient.Builder =
try {
// Create a trust manager that does not validate certificate chains
val trustAllCerts: Array<TrustManager> = arrayOf(
object : X509TrustManager {
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<X509Certificate?>?,
authType: String?) = Unit
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<X509Certificate?>?,
authType: String?) = Unit
override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
}
)
// Install the all-trusting trust manager
val sslContext: SSLContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, SecureRandom())
// Create an ssl socket factory with our all-trusting manager
val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory
val builder = OkHttpClient.Builder()
builder.sslSocketFactory(sslSocketFactory,
trustAllCerts[0] as X509TrustManager)
builder.hostnameVerifier { _, _ -> true }
builder
} catch (e: Exception) {
throw RuntimeException(e)
}
}
Run Code Online (Sandbox Code Playgroud)
如果使用Glide
,也会出现同样的错误,图像不会显示。要克服它,请参阅Glide - javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for Certification path not found和How to set OkHttpClient for glide。
@GlideModule
class MyAppGlideModule : AppGlideModule() {
val okHttpClient = Api.getOkHttpBuilder().build() // Api is the class written above.
// It is better to create okHttpClient here and not use Api.okHttpClient,
// because their settings may differ. For instance, it can use its own
// `addInterceptor` and `addNetworkInterceptor` that can affect on a read JSON.
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
registry.replace(GlideUrl::class.java, InputStream::class.java,
OkHttpUrlLoader.Factory(okHttpClient))
}
}
Run Code Online (Sandbox Code Playgroud)
构建.gradle:
// Glide.
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
Run Code Online (Sandbox Code Playgroud)
更新
我还在 API 16 模拟器上遇到了另一个错误:
例程:SSL23_GET_SERVER_HELLO:tlsv1 警报协议版本 (external/openssl/ssl/s23_clnt.c:741'.
okHttpClient = getOkHttpBuilder().build()
private fun getOkHttpBuilder(): OkHttpClient.Builder {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Security.insertProviderAt(Conscrypt.newProvider(), 1)
}
return OkHttpClient().newBuilder()
}
// build.gradle:
implementation 'org.conscrypt:conscrypt-android:2.5.1'
Run Code Online (Sandbox Code Playgroud)
我还从以下内容中删除了这些行MyApplication
:
try {
ProviderInstaller.installIfNeeded(applicationContext)
val sslContext = SSLContext.getInstance("TLSv1.2")
sslContext.init(null, null, null)
sslContext.createSSLEngine()
} catch (e: GooglePlayServicesRepairableException) {
Timber.e(e.stackTraceToString())
// Prompt the user to install/update/enable Google Play services.
GoogleApiAvailability.getInstance().showErrorNotification(this, e.connectionStatusCode)
} catch (e: GooglePlayServicesNotAvailableException) {
Timber.e(e.stackTraceToString())
// Prompt the user to install/update/enable Google Play services.
// GoogleApiAvailability.getInstance().showErrorNotification(this, e.errorCode)
} catch (e: NoSuchAlgorithmException) {
Timber.e(e.stackTraceToString())
} catch (e: KeyManagementException) {
Timber.e(e.stackTraceToString())
}
Run Code Online (Sandbox Code Playgroud)
但是该库为 apk 增加了 3.4 Mb。
我遇到了同样的问题,我发现我提供的证书 .crt 文件缺少中间证书。因此,我向服务器管理员询问了所有 .crt 文件,然后以相反的顺序将它们连接起来。
前任。1.Root.crt 2.Inter.crt 3.myCrt.crt
在Windows中我执行了copy Inter.crt + Root.crt newCertificate.crt
(这里我忽略了myCrt.crt)
然后我通过输入流将 newCertificate.crt 文件提供到代码中。完工。
我知道您不需要信任所有证书,但就我而言,我在一些调试环境中遇到了问题,在这些环境中我们有自签名证书,我需要一个肮脏的解决方案。
我所要做的就是更改sslContext
mySSLContext.init(null, trustAllCerts, null);
Run Code Online (Sandbox Code Playgroud)
在哪里trustAllCerts
创建是这样的:
private final TrustManager[] trustAllCerts= new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
Run Code Online (Sandbox Code Playgroud)
希望这会派上用场。
归档时间: |
|
查看次数: |
325530 次 |
最近记录: |