Java 错误:0c0890ba:ASN.1编码例程:asn1\u检查\t错误\u标记
我正在尝试在我的截击请求中实现ssl支持(我在SO中也看到了类似问题的答案,但这对我没有帮助) 在的帮助下,我将证书扩展名从.cer转换为.bks 根据我下一步做的Java 错误:0c0890ba:ASN.1编码例程:asn1\u检查\t错误\u标记,java,android,ssl,ssl-certificate,boringssl,Java,Android,Ssl,Ssl Certificate,Boringssl,我正在尝试在我的截击请求中实现ssl支持(我在SO中也看到了类似问题的答案,但这对我没有帮助) 在的帮助下,我将证书扩展名从.cer转换为.bks 根据我下一步做的 mRequestQueue = Volley.newRequestQueue(this, hurlStack); private HurlStack hurlStack = new HurlStack() { @Override protected HttpURLConnection createConnectio
mRequestQueue = Volley.newRequestQueue(this, hurlStack);
private HurlStack hurlStack = new HurlStack()
{
@Override
protected HttpURLConnection createConnection(URL url) throws IOException
{
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) super.createConnection(url);
try
{
httpsURLConnection.setSSLSocketFactory(getSSLSocketFactory());
httpsURLConnection.setHostnameVerifier(getHostnameVerifier());
}
catch (Exception e)
{
AppUtils.printLog(Log.ERROR, TAG, e.getMessage());
}
return httpsURLConnection;
}
};
private SSLSocketFactory getSSLSocketFactory() throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException
{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.keystore); // this cert file stored in \app\src\main\res\raw folder path
Certificate ca = cf.generateCertificate(caInput);
caInput.close();
KeyStore keyStore = KeyStore.getInstance("BKS");
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, wrappedTrustManagers, null);
return sslContext.getSocketFactory();
}
// Let's assume your server app is hosting inside a server machine
// which has a server certificate in which "Issued to" is "localhost",for example.
// Then, inside verify method you can verify "localhost".
// If not, you can temporarily return true
private HostnameVerifier getHostnameVerifier()
{
return new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session)
{
//return true; // verify always returns true, which could cause insecure network traffic due to trusting TLS/SSL server certificates for wrong hostnames
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
return hv.verify("localhost", session);
}
};
}
private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers)
{
final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
return new TrustManager[] {new X509TrustManager()
{
public X509Certificate[] getAcceptedIssuers()
{
return originalTrustManager.getAcceptedIssuers();
}
public void checkClientTrusted(X509Certificate[] certs, String authType)
{
try
{
if (certs != null && certs.length > 0)
{
certs[0].checkValidity();
}
else
{
originalTrustManager.checkClientTrusted(certs, authType);
}
}
catch (CertificateException e)
{
Log.w("checkClientTrusted", e.toString());
}
}
public void checkServerTrusted(X509Certificate[] certs, String authType)
{
try
{
if (certs != null && certs.length > 0)
{
certs[0].checkValidity();
}
else
{
originalTrustManager.checkServerTrusted(certs, authType);
}
}
catch (CertificateException e)
{
Log.w("checkServerTrusted", e.toString());
}
}
}};
}
我得到下一个错误
com.android.org.concrypt.OpenSSLX509CertificateFactory$ParsingException:com.android.org.concrypt.OpenSSLX509CertificateFactory$ParsingException:java.lang.RuntimeException:错误:0c0890ba:ASN.1编码例程:asn1\U检查\tlen:错误的\U标记
正因为如此,我得到了这样的回应
错误的请求
错误的请求-无效的标头
HTTP错误400。请求的标头名称无效
我做错了什么
请随便问
编辑1
现在我的getSSLSocketFactory()
方法如下所示
private SSLSocketFactory getSSLSocketFactory() throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException
{
InputStream ksInStream = getResources().openRawResource(R.raw.keystore);
KeyStore ks = KeyStore.getInstance("BKS");
ks.load(ksInStream, SslUtils.KEYSTORE_PASSWORD_SSL.toCharArray());
// Certificate cert = ks.getCertificate("alias");
// ks.setCertificateEntry("ca", cert);
ksInStream.close();
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(ks);
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, wrappedTrustManagers, null);
return sslContext.getSocketFactory();
}
现在我没有收到关于错误标签的消息,但我仍然收到错误响应
ResponseJsonString=
错误的请求
错误的请求-无效的标头
HTTP错误400。请求的标头名称无效
最终,我没有找到解决问题的方法,而是找到了另一种实现方法 因此,请关注本文 此外,如果在将
.cer
转换为.bks
方面存在任何问题,请在此回答我的问题
在这段代码中,您似乎以BKS格式加载密钥库,因为它将是X.509编码的证书,这注定会失败
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.elalkeystore);
Certificate ca = cf.generateCertificate(caInput);
caInput.close();
您可以按如下方式加载密钥库:
InputStream ksInStream = getResources().openRawResource(R.raw.elalkeystore);
KeyStore ks = KeyStore.getInstance("BKS");
ks.load(ksInStream, keystorePasswordCharArray);
Certificate cert = ks.getCertificate("entryAlias");
ksInStream.close();
从不同的来源来看,此问题与在用于转换的证书末尾提取尾随空格有关。仔细检查你的起始证书,确保它没有尾随空格或换行符。问题其实很简单。查看divanov的答案。@Nico我在
divanov
answer下留下了评论,你能看一下吗?但是根据你的答案,没有使用cert
值。我想你忘了提到这一行ks.setCertificateEntry(“ca”,cert)代码>,是吗?我想他确实忘了在他的示例中添加这一行。那么它应该像预期的那样工作。为什么要将证书添加到已有的密钥库中?我提取证书只是为了能够交叉检查密钥库是否确实有证书,并使其与被替换的代码类似。@divanov因此,如果我理解正确,我就不需要调用.setCertificateEntry()
方法了?不管怎样,我对我的编辑1提出了疑问,你能看一下吗?这个方法在密钥存储中添加了一个证书,而它原来是有证书的。我建议您收集连接尝试的tcpdump,然后与wireshark一起检查那里发生了什么。另外,原始错误错误错误请求-无效标头未更改,尽管您在TLS安装期间解决了异常。这让我怀疑这个错误是否与原来的问题有关,或者这个问题不准确。