gpt4 book ai didi

android - 如何在 Android 中禁用 ssl 关键扩展检查?

转载 作者:行者123 更新时间:2023-11-29 19:31:11 24 4
gpt4 key购买 nike

我使用 okHTTP 向我的 Android 应用程序中的服务器发送 HTTPS 请求。 Android 版本 > Jelly Bean 没问题,但 Jelly Bean 会抛出以下异常:

javax.net.ssl.SSLHandshakeException: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Certificate has unsupported critical extension
10-04 12:45:01.391 7570-7735/mop.orange.com.moplibapptest5 I/System.out: at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
10-04 12:45:01.391 7570-7735/mop.orange.com.moplibapptest5 I/System.out: at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:241)

它似乎链接到 SSL/TLS 服务器证书,该证书包含 2 个带有“critical”标签的扩展。我无法更改此证书,因为服务器不是我的。

我尝试启用/禁用 TLS 扩展支持,但行为是一样的:(

ConnectionSpec connSpec = new ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
.supportsTlsExtensions(false)
.build();

OkHttpClient.Builder()
.connectionSpecs(Collections.singletonList(connSpec))

请问您知道如何禁用 okHTTP(或似乎在下方的 Bouncy CaSTLe 中)的关键扩展检查吗?

最佳答案

我使用 okHTTP waycustomize受信任的证书,然后我包装 TrustManager 和证书以返回一个空的关键扩展列表。

这是 Jelly Bean 类时的 TrustManager 包装:

        if(trustManagers[0].getClass().toString().equals("class org.apache.harmony.xnet.provider.jsse.TrustManagerImpl")) {
logger.debug("Wrapping TrustManager to return no critical extension");
return new TrustManagerNoCritical((X509TrustManager) trustManagers[0]);
}

这里是 TrustManager 包装类,用于包装链中的证书:

public class TrustManagerNoCritical implements X509TrustManager  {

protected X509TrustManager trustManager;

public TrustManagerNoCritical(X509TrustManager realTrustManager) {
trustManager = realTrustManager;
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
trustManager.checkClientTrusted(chain, authType);
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

List<X509Certificate> certifs = new ArrayList<X509Certificate>();

for (X509Certificate certif : chain) {
certifs.add(new CertificateNoCritical(certif));
}

X509Certificate[] newChain = new X509Certificate[certifs.size()];
newChain = certifs.toArray(newChain);

trustManager.checkServerTrusted(newChain, authType);
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return trustManager.getAcceptedIssuers();
}

}

这是一个证书类,用于包装真实证书并且不返回任何关键扩展:

public class CertificateNoCritical extends X509Certificate {

protected X509Certificate certif;

public CertificateNoCritical(X509Certificate certificateToWrap) {
certif = certificateToWrap;
}


@Override
public boolean hasUnsupportedCriticalExtension() {
return certif.hasUnsupportedCriticalExtension();
}

@Override
public Set<String> getCriticalExtensionOIDs() {
// Return empty Set to avoid "critical extension" Exception
return new HashSet<String>();
}

@Override
public Set<String> getNonCriticalExtensionOIDs() {
return certif.getNonCriticalExtensionOIDs();
}

@Override
public byte[] getExtensionValue(String oid) {
return certif.getExtensionValue(oid);
}

@Override
public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException {
certif.checkValidity();
}

@Override
public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException {
certif.checkValidity(date);
}

@Override
public int getVersion() {
return certif.getVersion();
}

@Override
public BigInteger getSerialNumber() {
return certif.getSerialNumber();
}

@Override
public Principal getIssuerDN() {
return certif.getIssuerDN();
}

@Override
public Principal getSubjectDN() {
return certif.getSubjectDN();
}

@Override
public Date getNotBefore() {
return certif.getNotBefore();
}

@Override
public Date getNotAfter() {
return certif.getNotAfter();
}

@Override
public byte[] getTBSCertificate() throws CertificateEncodingException {
return certif.getTBSCertificate();
}

@Override
public byte[] getSignature() {
return certif.getSignature();
}

@Override
public String getSigAlgName() {
return certif.getSigAlgName();
}

@Override
public String getSigAlgOID() {
return certif.getSigAlgOID();
}

@Override
public byte[] getSigAlgParams() {
return certif.getSigAlgParams();
}

@Override
public boolean[] getIssuerUniqueID() {
return certif.getIssuerUniqueID();
}

@Override
public boolean[] getSubjectUniqueID() {
return certif.getSubjectUniqueID();
}

@Override
public boolean[] getKeyUsage() {
return certif.getKeyUsage();
}

@Override
public int getBasicConstraints() {
return certif.getBasicConstraints();
}

@Override
public byte[] getEncoded() throws CertificateEncodingException {
return certif.getEncoded();
}

@Override
public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
NoSuchProviderException, SignatureException {
certif.verify(key);
}

@Override
public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException {
certif.verify(key, sigProvider);
}

@Override
public String toString() {
return certif.toString();
}

@Override
public PublicKey getPublicKey() {
return certif.getPublicKey();
}

}

关于android - 如何在 Android 中禁用 ssl 关键扩展检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39912351/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com