我正在开发一个android应用程序,并使用SSL连接连接到我的服务器。
连接到我的web服务,我使用Volley请求到我的服务器https的地址。
但是,当我试图拦截我的连接使用包捕获,使用人在中间的方法拦截我的连接,它看起来像一个非SSL连接。我可以看到整个请求和响应。但是,像LINE, Facebook等其他应用程序无法通过数据包捕获来解密。我想保护我的网络服务,甚至不受同一设备的攻击,就像LINE和Facebook那样。我怎样才能做到呢?我不想让别人知道发送到我的web服务的任何参数。
我的后端服务器使用google云平台计算引擎。
编辑:我使用Letsencrypt.org SSL证书
代码:My Custom Request
public class CustomRestRequest extends Request<JSONObject> implements Serializable {
private static final String SERVER_URL = "https://myapiurl.com/";
private Map<String, String> mHeaders = new HashMap<>();
private Response.Listener<JSONObject> listener;
private Map<String, String> params;
public UberGUARestRequest(String action, Map<String, String> params,
Response.Listener<JSONObject> responseListener, Response.ErrorListener errorListener) {
super(Method.POST, SERVER_URL + action, errorListener);
this.listener = responseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
@Override
protected void deliverResponse(JSONObject response) {
listener.onResponse(response);
}
@Override
public Map<String, String> getHeaders() {
return mHeaders;
}
public void setBearerAuthorization(String token) {
mHeaders.put("Authorization", "Bearer " + token);
}
}
我的请求示例:
Map<String, String> params = new HashMap<>();
params.put("message", message);
final CustomRestRequest request = new CustomRestRequest("user/support", params,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
if (response.getString("status").equals("00")) {
result.status = "00";
mListener.onSupportTaskPostExecute(result);
} else {
result.status = "99";
isRunning = false;
mListener.onSupportTaskPostExecute(result);
}
} catch (Exception ex) {
result.status = "99";
isRunning = false;
mListener.onSupportTaskPostExecute(result);
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
result.status = "88";
isRunning = false;
mListener.onSupportTaskPostExecute(result);
error.printStackTrace();
}
});
request.setBearerAuthorization(AppHelper.getAuthCode(getContext()));
RequestQueue queue = Volley.newRequestQueue(getContext());
queue.add(request);
只要攻击者拥有您的设备接受的证书,SSL就容易受到MitM攻击。*
您的设备主要接受两种类型的证书:由可信组织(如Verisign或Thawte)颁发的证书和您自己安装的证书。
我怀疑数据包捕获,如果这是你正在使用的,正在设备上安装自己的证书,使其受信任,以后能够在传出连接上欺骗任何证书。
好消息是,任何来自外部的mitm攻击都不应该那么容易做到同样的事情。(在某些情况下,这仍然是可能的,比如以可疑的理由说服你安装一个应用程序或证书)。
为了完全防止这种情况,您可以使用证书固定来确保您的连接不能用不同的证书重新加密。
您还应该尝试从设备外部进行mitm攻击,例如使用像Charles这样的代理来有效地查看您的连接是否仍然安全。
*: SSL不能保证证书和域名之间的链接。它只保证签署连接的人应该是可信的。(加一大块盐食用。任何人都可以购买几乎不需要验证的证书。