我在与企业设备建立 SSL 连接时遇到了问题。当我在普通的 android 设备上运行我的应用程序时,SSL 握手会成功。我不知道为什么会发生这种情况,代码应该适用于这两种设备。
这是我选择证书和提取别名私有和证书链的代码:
public void userAliasCertificateSelection() {
boolean isGranted = appPreferences.getPrefrenceBoolean("mycertificate");
if (!isGranted) {
//Get cert and private key from internal android store
KeyChain.choosePrivateKeyAlias(this, new KeyChainAliasCallback() {
@Override
public void alias(@Nullable String s) {
appPreferences.setPrefrenceString("CertificateAlias",s);
appPreferences.setPrefrenceBoolean("mycertificate", true);
asyncTask.execute();
}
}, new String[]{KeyProperties.KEY_ALGORITHM_RSA}, null, null, -1, null);
} else {
asyncTask.execute();
}
}
@SuppressLint("StaticFieldLeak")
AsyncTask<Void, Void, Boolean> asyncTask = new AsyncTask<Void, Void, Boolean>() {
private Exception error;
@Override
protected Boolean doInBackground(Void... arg) {
try {
PrivateKey pk = KeyChain.getPrivateKey(DiallerViewActivity.this, appPreferences.getPrefrenceString("CertificateAlias"));
X509Certificate[] chain = KeyChain.getCertificateChain(DiallerViewActivity.this, appPreferences.getPrefrenceString("CertificateAlias"));
byte[] data = "foobar".getBytes("ASCII");
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(pk);
sig.update(data);
byte[] signed = sig.sign();
PublicKey pubk = chain[0].getPublicKey();
sig.initVerify(pubk);
sig.update(data);
boolean valid = sig.verify(signed);
Log.d(TAG, "signature is valid: " + valid);
if(valid) {
mPrivateKey = pk;
mCertificates = chain;
}
return valid;
} catch (Exception e) {
e.printStackTrace();
error = e;
return null;
}
}
@Override
protected void onPostExecute(Boolean valid) {
if (error != null) {
return;
}else{
connect(appPreferences.getPrefrenceString("CertificateAlias"));
}
}
};
现在用 OkHttpClient 绑定它:
private void connect(String mAlias){
String alias = mAlias;
KeyStore trustStore = null;
try {
trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
} catch (KeyStoreException e) {
e.printStackTrace();
}
X509ExtendedKeyManager keyManager = new X509ExtendedKeyManager() {
@Override
public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
return alias;
}
@Override
public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
return alias;
}
@Override
public X509Certificate[] getCertificateChain(String s) {
return mCertificates;
}
@Override
public String[] getClientAliases(String s, Principal[] principals) {
return new String[]{alias};
}
@Override
public String[] getServerAliases(String s, Principal[] principals) {
return new String[]{alias};
}
@Override
public PrivateKey getPrivateKey(String s) {
return mPrivateKey;
}
};
TrustManagerFactory trustFactory = null;
try {
trustFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(trustStore);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (KeyStoreException e) {
e.printStackTrace();
}
TrustManager[] trustManagers = trustFactory.getTrustManagers();
X509TrustManager[] tm = new X509TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return mCertificates;
}
} };
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
sslContext.init(new KeyManager[] {keyManager}, tm, null);
SSLContext.setDefault(sslContext);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
okClient = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory())
.build();
}
此代码适用于普通设备,但不适用于企业设备。
如果我需要为企业设备做点什么,请告诉我。
问候