HTTPS android 到服务器通信总是 returns 403 响应
Https android to server communication always returns 403 response
过去两天我一直坚持这个问题,我必须使用客户端证书对服务器实施相互身份验证。我的 .pfx 文件位于 res 目录中的 raw 文件夹中。
我在 res/raw/certificate.pfx
我还在 android 中实现了 HttpUrlConnection 并将 SSLSocketFactory 设置为我从我的证书生成的那个。但问题是服务器总是 returns 403。我尝试添加所有请求 属性,包括 "User Agent"。但似乎没有任何效果。
我附上了下面的代码。我信任这样的证书。
public SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId)
throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException, NoSuchProviderException {
InputStream caInput = context.getResources().openRawResource(keystoreResId);
// creating a KeyStore containing trusted CAs
if (keyStoreType == null || keyStoreType.length() == 0) {
keyStoreType = KeyStore.getDefaultType();
}
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(caInput, "".toCharArray());
// creating a TrustManager that trusts the CAs in the KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, wrappedTrustManagers, null);
return sslContext.getSocketFactory();
}
最后在我的 activity 中,我按如下方式进行 https 调用
URL url = null;
HttpURLConnection conn;
try {
url = new URL("https://example.com");
conn = (HttpURLConnection) url.openConnection();
if (conn instanceof HttpsURLConnection) {
((HttpsURLConnection) conn).setSSLSocketFactory(sslSocketFactory);
}
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
int responseCode = conn.getResponseCode();
System.out.println("Server response code" + responseCode);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
但是结果总是403 forbidden。我不确定我哪里出错了。有人请帮助我。
啊..终于我自己找到了问题。我所缺少的是我在加载证书后未能使用密钥库初始化我的密钥库工厂。
public SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId)
throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException, NoSuchProviderException, UnrecoverableKeyException {
InputStream caInput = context.getResources().openRawResource(keystoreResId);
// creating a KeyStore containing trusted CAs
if (keyStoreType == null || keyStoreType.length() == 0) {
keyStoreType = KeyStore.getDefaultType();
}
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(caInput, "".toCharArray());
// creating a TrustManager that trusts the CAs in the KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "".toCharArray());
sslContext.init(kmf.getKeyManagers(), wrappedTrustManagers, null);
return sslContext.getSocketFactory();
}
这些台词对我有用。
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "".toCharArray());
sslContext.init(kmf.getKeyManagers(), wrappedTrustManagers, null);
希望它能对某人有所帮助。 :)
过去两天我一直坚持这个问题,我必须使用客户端证书对服务器实施相互身份验证。我的 .pfx 文件位于 res 目录中的 raw 文件夹中。
我在 res/raw/certificate.pfx
我还在 android 中实现了 HttpUrlConnection 并将 SSLSocketFactory 设置为我从我的证书生成的那个。但问题是服务器总是 returns 403。我尝试添加所有请求 属性,包括 "User Agent"。但似乎没有任何效果。
我附上了下面的代码。我信任这样的证书。
public SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId)
throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException, NoSuchProviderException {
InputStream caInput = context.getResources().openRawResource(keystoreResId);
// creating a KeyStore containing trusted CAs
if (keyStoreType == null || keyStoreType.length() == 0) {
keyStoreType = KeyStore.getDefaultType();
}
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(caInput, "".toCharArray());
// creating a TrustManager that trusts the CAs in the KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, wrappedTrustManagers, null);
return sslContext.getSocketFactory();
}
最后在我的 activity 中,我按如下方式进行 https 调用
URL url = null;
HttpURLConnection conn;
try {
url = new URL("https://example.com");
conn = (HttpURLConnection) url.openConnection();
if (conn instanceof HttpsURLConnection) {
((HttpsURLConnection) conn).setSSLSocketFactory(sslSocketFactory);
}
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
int responseCode = conn.getResponseCode();
System.out.println("Server response code" + responseCode);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
但是结果总是403 forbidden。我不确定我哪里出错了。有人请帮助我。
啊..终于我自己找到了问题。我所缺少的是我在加载证书后未能使用密钥库初始化我的密钥库工厂。
public SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId)
throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException, NoSuchProviderException, UnrecoverableKeyException {
InputStream caInput = context.getResources().openRawResource(keystoreResId);
// creating a KeyStore containing trusted CAs
if (keyStoreType == null || keyStoreType.length() == 0) {
keyStoreType = KeyStore.getDefaultType();
}
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(caInput, "".toCharArray());
// creating a TrustManager that trusts the CAs in the KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "".toCharArray());
sslContext.init(kmf.getKeyManagers(), wrappedTrustManagers, null);
return sslContext.getSocketFactory();
}
这些台词对我有用。
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "".toCharArray());
sslContext.init(kmf.getKeyManagers(), wrappedTrustManagers, null);
希望它能对某人有所帮助。 :)