1、需求,使用以下三个文件做双向认证
a. 服务端证书文件
b. 客户端证书文件
c. 私钥
2、代码实现
import android.content.Context;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Collection;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
/**
* @author azu
* @data
* @describe
*/
public class NetworkVerifier {
private final static String CERTIFICATE_STANDARD = "X.509";
//私钥
private final static String CLIENT_PRIVATE_KEY = "cloud.com.key";
private final static String SERVER = "server";
//服务端证书
private final static String SERVER_CERTIFICATE = "Root.pem";
private final static String CLIENT = "client";
//客户端证书
private final static String CLIENT_CERTIFICATE = "cloud.com.crt";
private final static String PROTOCOL_TYPE = "TLS";
private static KeyStore getServerKeyStore(Context context) {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_STANDARD);
// 从文件中获取
InputStream inputStream = context.getAssets().open(SERVER_CERTIFICATE);
Collection<Certificate> certificateCollection = (Collection<Certificate>) certificateFactory.generateCertificates(inputStream);
Certificate[] certificates = new Certificate[certificateCollection.size()];
KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
clientKeyStore.load(null);
int i = 0;
for (Certificate certificate : certificateCollection) {
certificates[i++] = certificate;
clientKeyStore.setCertificateEntry(SERVER + i, certificate);
}
inputStream.close();
return clientKeyStore;
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static KeyStore getClientKeyStore(Context context) {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_STANDARD);
// 从文件中获取
InputStream inputStream = context.getAssets().open(CLIENT_CERTIFICATE);
Collection<Certificate> certificateCollection = (Collection<Certificate>) certificateFactory.generateCertificates(inputStream);
Certificate[] certificates = new Certificate[certificateCollection.size()];
KeyStore serverKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
serverKeyStore.load(null);
int i = 0;
for (Certificate certificate : certificateCollection) {
certificates[i++] = certificate;
serverKeyStore.setCertificateEntry(CLIENT + i, certificate);
}
inputStream.close();
InputStream rsaInputStream = context.getAssets().open(CLIENT_PRIVATE_KEY);
PEMParser pemParser = new PEMParser(new InputStreamReader(rsaInputStream));
PEMKeyPair kp = (PEMKeyPair) pemParser.readObject();
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
PrivateKey privateKey = converter.getKeyPair(kp).getPrivate();
serverKeyStore.setKeyEntry(CLIENT, privateKey, null//"123456".toCharArray()
, certificates);
rsaInputStream.close();
return serverKeyStore;
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
return null;
}
public static void addSSL(Context context, OkHttpClient.Builder builder) {
try {
KeyStore clientKeyStore = getClientKeyStore(context);
KeyStore serverKeyStore = getServerKeyStore(context);
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore, null/*"123456".toCharArray()*/);
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(serverKeyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
//SSLContext
SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, new SecureRandom());
builder.sslSocketFactory(sslContext.getSocketFactory(), trustManager);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
//强行返回true 即验证成功
return true;
}
});
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
}
3、依赖包,百度查找吧
1、bcpkix-jdk15on-1.54.jar
2、bcprov-jdk15on-1.54.jar
网友评论