以编程方式将服务器证书信息添加到 Trust Manager Android
Posted
技术标签:
【中文标题】以编程方式将服务器证书信息添加到 Trust Manager Android【英文标题】:Add Server Certificate Information to Trust Manager Android Programmatically 【发布时间】:2015-07-22 22:14:27 【问题描述】:我是这个 SSL
和 X509Certificate
概念的新手。我所需要的是,有没有办法从给定的Url
获取证书信息
例如:如果用户输入了https://www.google.com,那么我需要以编程方式获得该证书信息。
编辑:
最后,我得到了来自服务器的证书信息。
现在,我的问题是:
1.如何检查证书是否可信?
2.如何将证书添加到信任管理器?
3. 即使它是不受信任的证书,如果用户想继续使用它,那么我需要将证书添加到信任管理器。我怎样才能做到这一点?
4.为了检查证书是否可信,我们真的需要另一个证书来比较吗?
我对这些X.509 Certificate.
非常陌生
我们将非常感谢任何帮助。
编辑:
这是我尝试过的。但是,他们都没有帮助我。我需要获得证书是否受信任。
X509TrustManager trustManager = new X509TrustManager()
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException
for (TrustManager tm : managers)
if (tm instanceof X509TrustManager)
((X509TrustManager) tm).checkClientTrusted(
chain, authType);
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType)
for (X509Certificate cert : chain)
final String mCertificatinoType = cert.getType();
Date afterDate = cert.getNotAfter();
Date beforeDate = cert.getNotBefore();
Date currentDate = new Date();
try
cert.checkValidity(new Date());
catch (CertificateExpiredException e)
LoginActivity.isExpired = true;
e.printStackTrace();
catch (CertificateNotYetValidException e)
LoginActivity.isInValid = true;
e.printStackTrace();
try
cert.verify(trustedRoot.getPublicKey());
catch (InvalidKeyException e)
e.printStackTrace();
catch (CertificateException e)
e.printStackTrace();
catch (NoSuchAlgorithmException e)
e.printStackTrace();
catch (NoSuchProviderException e)
e.printStackTrace();
catch (SignatureException e)
e.printStackTrace();
try
if (cert.getIssuerX500Principal().equals(
trustedRoot.getIssuerX500Principal()))
cert.verify(trustedHost.getPublicKey());
catch (InvalidKeyException e)
e.printStackTrace();
catch (CertificateException e)
e.printStackTrace();
catch (NoSuchAlgorithmException e)
e.printStackTrace();
catch (NoSuchProviderException e)
e.printStackTrace();
catch (SignatureException e)
e.printStackTrace();
if (afterDate.compareTo(currentDate)
* currentDate.compareTo(beforeDate) > 0)
else
if (cert.getIssuerX500Principal().equals(
trustedRoot.getIssuerX500Principal()))
return;
// for (X509Certificate cert : chain)
// URL url;
// String host = "";
// if (baseHostString.equalsIgnoreCase(""))
// final Settings settings = mApplication
// .getSettings();
// try
// url = new URL(
// settings.serverAddress.toString());
// host = url.getAuthority();
// catch (MalformedURLException e)
// e.printStackTrace();
//
// else
//
//
//
// String dn = cert.getSubjectDN().getName();
// String CN = getValByAttributeTypeFromIssuerDN(dn,
// "CN=");
// if (CN.equalsIgnoreCase(host))
// if (cert.getIssuerX500Principal().equals(
// trustedRoot.getIssuerX500Principal()))
// return;
// else
//
// else
//
//
for (TrustManager tm : managers)
if (tm instanceof X509TrustManager)
try
((X509TrustManager) tm).checkServerTrusted(
chain, authType);
catch (CertificateException e)
e.printStackTrace();
@Override
public X509Certificate[] getAcceptedIssuers()
ArrayList<X509Certificate> issuers = new ArrayList<>();
for (TrustManager tm : managers)
if (tm instanceof X509TrustManager)
issuers.addAll(Arrays
.asList(((X509TrustManager) tm)
.getAcceptedIssuers()));
return issuers.toArray(new X509Certificate[issuers
.size()]);
;
【问题讨论】:
Using openssl to get the certificate from a server的可能重复 您想使用 android Java 还是使用 OpenSSL?而拿到证书后你想做什么? 使用 Android Java...我需要将该证书添加到信任管理器中......并且也应该允许该不受信任的服务器证书@jww。您分享的链接不同 @jww 这不是那个的副本。 @EpicPandaForce: 有没有办法检查 X509 证书是否可信? 【参考方案1】:终于破解了!
X509TrustManager trustManager = new X509TrustManager()
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException
for (TrustManager tm : managers)
if (tm instanceof X509TrustManager)
((X509TrustManager) tm).checkClientTrusted(
chain, authType);
@Override
public void checkServerTrusted(
final X509Certificate[] chain, String authType)
for (X509Certificate cert : chain)
final String mCertificatinoType = cert.getType();
Date afterDate = cert.getNotAfter();
Date beforeDate = cert.getNotBefore();
Date currentDate = new Date();
try
cert.checkValidity(new Date());
catch (CertificateExpiredException e)
isExpired = true;
e.printStackTrace();
catch (CertificateNotYetValidException e)
isInValid = true;
e.printStackTrace();
if (afterDate.compareTo(currentDate)
* currentDate.compareTo(beforeDate) > 0)
isExpired = false;
else
isExpired = true;
String dn = cert.getSubjectDN().getName();
String CN = getValByAttributeTypeFromIssuerDN(dn,
"CN=");
String host = "";
if (TextUtils.isEmpty(query))
if (baseHostString.equalsIgnoreCase(""))
final Settings settings = mApplication
.getSettings();
try
URL url = new URL(
settings.serverAddress
.toString());
host = url.getAuthority();
if (host.contains(String.valueOf(url
.getPort())))
String toBeReplaced = ":"
+ url.getPort();
host = host.replace(toBeReplaced,
"");
catch (MalformedURLException e)
e.printStackTrace();
else
try
URL url = new URL(baseHostString);
host = url.getAuthority();
if (host.contains(String.valueOf(url
.getPort())))
String toBeReplaced = ":"
+ url.getPort();
host = host.replace(toBeReplaced,
"");
catch (MalformedURLException e)
e.printStackTrace();
else
try
URL url = new URL(query);
host = url.getAuthority();
if (host.contains(String.valueOf(url
.getPort())))
String toBeReplaced = ":"
+ url.getPort();
host = host.replace(toBeReplaced, "");
catch (MalformedURLException e)
e.printStackTrace();
if (CN.equalsIgnoreCase(host))
isHostMisMatch = false;
else
isHostMisMatch = true;
for (TrustManager tm : managers)
if (tm instanceof X509TrustManager)
try
((X509TrustManager) tm)
.checkServerTrusted(chain,
authType);
catch (CertificateException e)
if (e.getMessage() != null
&& e.getMessage()
.contains(
"Trust anchor for certification path not found."))
isNotTrusted = true;
mApplication
.setCurrentCertificate(chain);
e.printStackTrace();
if (cert.getIssuerX500Principal().equals(
trustedRoot.getIssuerX500Principal()))
return;
@Override
public X509Certificate[] getAcceptedIssuers()
ArrayList<X509Certificate> issuers = new ArrayList<>();
for (TrustManager tm : managers)
if (tm instanceof X509TrustManager)
issuers.addAll(Arrays
.asList(((X509TrustManager) tm)
.getAcceptedIssuers()));
return issuers.toArray(new X509Certificate[issuers
.size()]);
;
谢谢大家。
【讨论】:
以上是关于以编程方式将服务器证书信息添加到 Trust Manager Android的主要内容,如果未能解决你的问题,请参考以下文章