我是android新手。我已经为ios编写了代码,并希望在android中使用类似的算法。
这是场景。我有两种类型的服务器 - 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;
}
}
}
在android中我找不到这样的TrustEvaluate
方法。我尝试了getBasicConstraints
和getKeyUsage
。但我无法区分签名证书和其他证书。
请帮帮我。
答案 0 :(得分:0)
尝试此代码,它可能与您的IOS算法不相似,但它可以正常工作。
如果您尝试将自签名服务器与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();
}
}
}