Godaddy 256bit SSL証明書を実行しているIIS 6ボックスに接続しようとしていますが、エラーが発生しています。
Java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
何が原因となっているのかを突き止めようとしていましたが、今は空白を描画しています。
これが私が接続している方法です:
HttpsURLConnection conn;
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream());
@Chrispixの解決策は危険です! すべての証明書を信頼すれば、誰でも攻撃を仕掛けることができます!証明書をクライアントに送信するだけで、それが受け入れられます。
この記事で説明しているように、カスタムの信頼マネージャに証明書を追加します。 HTTPS経由でHttpClientを使用してすべての証明書を信頼する
カスタム証明書を使用して安全な接続を確立するのは少し複雑ですが、中間攻撃の危険なしに、必要なSSL暗号化セキュリティを実現できます。
承認された回答とは反対にしないカスタムの信頼マネージャは必要ありません、サーバーを修正する必要があります構成!
正しくインストールされていないdynadot/alphassl証明書を使用してApacheサーバーに接続しているときに同じ問題が発生しました。投げていたHttpsUrlConnection(Java/Android)を使って接続しています -
javax.net.ssl.SSLHandshakeException:
Java.security.cert.CertPathValidatorException:
Trust anchor for certification path not found.
実際の問題はサーバの設定ミスです - http://www.digicert.com/help/ かそれに類似したものでテストしてください。
「証明書は信頼できる機関によって署名されていません(Mozillaのルートストアと照合)。信頼できる機関から証明書を購入した場合は、おそらくインストールする必要があります。 1つ以上の中間証明書。ご使用のサーバープラットフォームでこれを行うには、証明書プロバイダにお問い合わせください。」
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`
証明書チェーンに含まれる要素は1つだけです(あなたの証明書)。
Certificate chain
0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
i:/O=AlphaSSL/CN=AlphaSSL CA - G2
...しかし、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
サーバーを構成するための指示(および中間証明書)は、通常、証明書を発行した機関によって提供されます。例えば、 http://www.alphassl.com/support/install-root-certificate.html =
証明書の発行者から提供された中間証明書をインストールした後、HttpsUrlConnectionを使用して接続するときにエラーが発生しなくなりました。
実行時に特定の証明書を信頼することができます。
サーバーからダウンロードし、アセットに入れて ssl-utils-Android を使用してこのようにロードするだけです。
OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());
上記の例ではOkHttpClient
を使用しましたが、SSLContext
はJavaのどのクライアントでも使用できます。
ご質問がありましたらお気軽にお尋ねください。私はこの小さな図書館の作者です。
最新の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)
問題は次のいずれかです。
解決策は、特定のCAのセットを信頼するようにHttpsURLConnection
を教えることです。どうやって?チェックしてください https://developer.Android.com/training/articles/security-ssl.html#CommonProblems
com.loopj.Android:android-async-http
ライブラリのAsyncHTTPClient
を使用している他の人は、 HTTPSを使用するようにAsyncHttpClientを設定 を確認してください。
非常に古い投稿に返信しています。しかし、多分それはいくつかの初心者を助け、上記のどれでも解決しないならば。
説明:私は誰も説明がらくたを望んでいないことを知っています。むしろ解決策です。しかし、あるライナーでは、あなたはあなたのローカルマシンからあなたのマシンを信頼しないリモートマシンへのサービスにアクセスしようとしています。あなたはリモートサーバーから信頼を得る必要があると要求します。
Solution:以下の解決策はあなたが以下の条件を満たしていることを前提としています
ステップ数
アプリにサインアップするには、.keystore拡張子ファイルが必要です。 .keystoreファイルの作成方法がわからない場合その後、次の手順に従ってくださいセクション.keystoreファイルを作成するまたはそうでなければ次のセクションにスキップします署名APKファイル
.keystoreファイルを作成する
Android Studioを開きます。トップメニュー[構築]> [署名付きAPKの生成]をクリックします。次のウィンドウでCreate new ...ボタンをクリックしてください。新しいウィンドウで、すべてのフィールドにデータを入力してください。 2つのパスワードフィールドを覚えておいてください。私は同じパスワードを使うべきです。別のパスワードを使用しないでください。また、一番上のフィールドの保存パスも覚えておいてくださいKey store path:。すべてのフィールドを入力したら、[OK]ボタンをクリックしてください。
Sign Apk File
これで、作成したばかりの.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"
}
}
下の2つのSignature Versions
チェックボックスをクリックしてFinish
ボタンをクリックします。
ほぼあります
すべてのハードワーク、今真実の動きが行われています。プロキシでバックアップされたステージングサーバーにアクセスするには、実際のテスト用Androidデバイスで何らかの設定を行う必要があります。
Androidデバイスのプロキシ設定:
Modify network
を選択Advanced options
フィールドが表示されない場合は、Proxy Hostname
をクリックしてください。Proxy Hostname
に、接続したいホストIPまたは名前を入力します。一般的なステージングサーバーはstg.api.mygoodcompany.com
という名前になります。9502
)。Save
ボタンを押す最後の1駅
署名したapkファイルをSign APK Fileセクションに生成したことを忘れないでください。今がその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
として入力します問題が解決することを願っています。そうでなかったら私にコメントを残しなさい。
サラム!
私が得ていたエラーメッセージは似ていました、しかしその理由は自己署名証明書が期限切れだったということでした。 opensslクライアントが試みられたとき、それは私がFirefoxから証明書ダイアログをチェックしていたときに見落とされていた理由を私に与えました。
そのため、一般的に、証明書がキーストアに存在し、その「有効」であれば、このエラーは発生しません。
後付けを使用する場合は、OkHttpClientをカスタマイズする必要があります。
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;
}
}
AndroidクライアントからKurentoサーバーへの接続中に同じ問題が発生しました。 Kurentoサーバーはjks証明書を使うので、pemをそれに変換する必要がありました。変換のための入力として私はcert.pemファイルを使いました、そしてそれはそのようなエラーを引き起こします。しかし、cert.pemの代わりにfullchain.pemを使用すれば、すべて問題ありません。
私はあなたがすべての証明書を信頼する必要はないことを知っていますが、私の場合私たちが自己署名証明書を持っていたいくつかのデバッグ環境で問題を抱えていました。
私がしなければならなかったのはsslContext
の初期化を変更することだけでした
mySSLContext.init(null, trustAllCerts, null);
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 {
}
} };
これが便利になることを願っています。
私が見つけたものと同じ問題を抱えていたのは、証明書.crtファイルに中間証明書がないことです。だから私は私のサーバー管理者からすべての.crtファイルを尋ねて、それからそれらを逆の順序で連結した。
例1. Root.crt 2. Inter.crt 3. myCrt.crt
windowsで私はコピーInter.crt + Root.crt newCertificate.crtを実行しました
(ここで私はmyCrt.crtを無視しました)
それから私は入力ストリームを介してコードにnewCertificate.crtファイルを提供しました。仕事は終わった。
トラストアンカーエラーは多くの理由で発生する可能性があります。私にとっては、単にhttps://example.com/
ではなくhttps://www.example.com/
にアクセスしようとしているだけでした。
ですから、私がやったようにあなた自身のトラストマネージャを構築し始める前にあなたのURLを再確認したいかもしれません。
ジンジャーブレッド電話では、私はいつもこのエラーを受け取ります:私が私の証明書に頼るように設定したとしても、Trust Anchor not found for Android SSL Connection
.
これが私が使うコードです(Scala言語で):
object Security {
private def createCtxSsl(ctx: Context) = {
val cer = {
val is = ctx.getAssets.open("mycertificate.crt")
try
CertificateFactory.getInstance("X.509").generateCertificate(is)
finally
is.close()
}
val key = KeyStore.getInstance(KeyStore.getDefaultType)
key.load(null, null)
key.setCertificateEntry("ca", cer)
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
tmf.init(key)
val c = SSLContext.getInstance("TLS")
c.init(null, tmf.getTrustManagers, null)
c
}
def prepare(url: HttpURLConnection)(implicit ctx: Context) {
url match {
case https: HttpsURLConnection ⇒
val cSsl = ctxSsl match {
case None ⇒
val res = createCtxSsl(ctx)
ctxSsl = Some(res)
res
case Some(c) ⇒ c
}
https.setSSLSocketFactory(cSsl.getSocketFactory)
case _ ⇒
}
}
def noSecurity(url: HttpURLConnection) {
url match {
case https: HttpsURLConnection ⇒
https.setHostnameVerifier(new HostnameVerifier {
override def verify(hostname: String, session: SSLSession) = true
})
case _ ⇒
}
}
}
これが接続コードです。
def connect(securize: HttpURLConnection ⇒ Unit) {
val conn = url.openConnection().asInstanceOf[HttpURLConnection]
securize(conn)
conn.connect();
....
}
try {
connect(Security.prepare)
} catch {
case ex: SSLHandshakeException /*if ex.getMessage != null && ex.getMessage.contains("Trust anchor for certification path not found")*/ ⇒
connect(Security.noSecurity)
}
基本的に、私は私のカスタム証明書を信頼するように設定しました。それが失敗した場合、私はセキュリティを無効にします。これは最良の選択肢ではありませんが、私が古くてバグのある電話で知っている唯一の選択肢です。
このサンプルコードは、簡単にJavaに翻訳できます。
私の場合、これはAndroid 8.0へのアップデート後に起こっていました。 Androidが信頼するように設定された自己署名証明書は、署名アルゴリズムSHA1withRSAを使用していました。署名アルゴリズムSHA256withRSAを使用して新しい証明書に切り替えると、問題が解決しました。