Поиск подписи SSL-сертификата

Я новичок в Android. Я написал код для IOS и хочу аналогичный алгоритм в Android.

Вот сцена. У меня есть 2 типа серверов - 1. с самоподписанным сертификатом 2. с подписанным сертификатом.

Теперь в IOS я использую следующие шаги, чтобы решить, подписан он или нет.

STACK_OF (X509) * stX509Certificate = SSL_get_peer_cert_chain (ssl); int cert_num = sk_X509_num (stX509Certificate);

CFMutableArrayRef certArray = CFArrayCreateMutable(NULL, cert_num, NULL);

for (int i = 0; i < cert_num; i++) {
    unsigned char *raw = NULL;

    X509 *x509Certificate = sk_X509_value(stX509Certificate, i);
    int rawlen = i2d_X509(x509Certificate, &raw);
    CFDataRef cfcert = CFDataCreate(NULL, raw, rawlen);
    free(raw);

    SecCertificateRef secCertRef = SecCertificateCreateWithData(NULL, cfcert);
    CFRelease(cfcert);

    CFArrayAppendValue(certArray, secCertRef);
}

CFStringRef servAddr = CFStringCreateWithCString(NULL, [[srvSplit objectAtIndex:0] cStringUsingEncoding:NSUTF8StringEncoding], kCFStringEncodingUTF8);
SecPolicyRef secPolRef = SecPolicyCreateSSL(YES, servAddr);
CFRelease(servAddr);

SecTrustRef secTruRef ;
SecTrustResultType secTrustRes;
Boolean isCertTrusted = NO;
if(SecTrustCreateWithCertificates(certArray, secPolRef, &secTruRef) == errSecSuccess) {
    SecTrustSetAnchorCertificatesOnly(secTruRef, NO);
    if (SecTrustEvaluate(secTruRef,&secTrustRes) == errSecSuccess) {
        switch (secTrustRes) {
            case kSecTrustResultInvalid:
            case kSecTrustResultDeny:
            case kSecTrustResultRecoverableTrustFailure:
            case kSecTrustResultFatalTrustFailure:
            case kSecTrustResultOtherError:
                isCertTrusted = NO;
                break;
            case kSecTrustResultUnspecified:
            case kSecTrustResultProceed:
                isCertTrusted = YES;
                break;
        }
    }
}

В андроиде не могу найти такой TrustEvaluate метод. Я старался getBasicConstraints а также getKeyUsage, Но я не могу отличить подписанные и другие сертификаты.

Пожалуйста, помогите мне.

1 ответ

Попробуйте этот код, он может не совпадать с вашим алгоритмом IOS, но работает нормально.

  • Добавьте свой собственный сертификат в /res/raw
  • Сначала этот код проверяет системные сертификаты Android (доверенные учетные данные), в этом случае, если вы подключаетесь к сертифицированному CA-серверу, он проверяет ваш сертификат и позволяет подключиться к серверу.
  • Если вы пытаетесь подключить самоподписанный сервер, он проверяет ваш самоподписанный сертификат, который находится в /res/raw
  • Если вы пытаетесь подключить самозаверяющий сервер с IP-адресом, тогда ваш сертификат должен содержать subjectAltName

    public class CheckCertificate{
    
    private static class NewCustomTrustManager implements X509TrustManager{
    
    private X509TrustManager defaultTrustManager;
    private X509TrustManager localTrustManager;
    public NewCustomTrustManager(KeyStore localKeyStore) throws KeyStoreException {
        try {
            this.defaultTrustManager = createNewTrustManager(null);
            this.localTrustManager = createNewTrustManager(localKeyStore);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
    private X509TrustManager createNewTrustManager(KeyStore store) throws NoSuchAlgorithmException, KeyStoreException {           
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();            
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(store);            
        TrustManager[] trustManagers = tmf.getTrustManagers();
        return (X509TrustManager) trustManagers[0];
    }
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        try {
            //Checks system certificate
            defaultTrustManager.checkServerTrusted(chain, authType);
        } catch (CertificateException ce) {
            //Checks your self signed certificate
            localTrustManager.checkServerTrusted(chain, authType);
        }
    }
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    
    
    
    @Override
    public X509Certificate[] getAcceptedIssuers() {
        X509Certificate[] first = defaultTrustManager.getAcceptedIssuers();
        X509Certificate[] second = localTrustManager.getAcceptedIssuers();
        X509Certificate[] result = Arrays.copyOf(first, first.length + second.length);
        return result;
      }
     }
     public static void setCustomCertificate(Context cn) {
    
    try {
        // Load CAs from an InputStream
        // (could be from a resource or ByteArrayInputStream or ...)
        CertificateFactory cf = CertificateFactory.getInstance("X.509");          
        InputStream caInput = new BufferedInputStream(cn.getResources().openRawResource(R.raw.apache_25));
    
        try {
            ca = cf.generateCertificate(caInput);
    
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            caInput.close();
        }
    
        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("cacertificate", ca);
    
        // Create a TrustManager that trusts the CAs in our KeyStore and system CA
        NewCustomTrustManager trustManager = new NewCustomTrustManager(keyStore);
    
        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, new TrustManager[]{trustManager}, null);
    
        // Tell the URLConnection to use a SocketFactory from our SSLContext
        HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
    
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
    
    }
    
Другие вопросы по тегам