如何防止数据包捕获解密我的 SSL 连接
How to prevent packet capture decrypt my SSL connection
我正在开发 android 应用程序并使用 SSL 连接连接到我的服务器。
为了连接到我的网络服务,我使用 Volley Request 到我的服务器 https 地址。
但是,当我尝试使用 Packet Capture 拦截我的连接时,它使用 man in the middle 方法来拦截我的连接,它看起来像一个非 SSL 连接。我可以看到整个请求和响应。
但是,其他应用程序如 LINE、Facebook 无法通过 Packet Capture 解密。我想保护我的网络服务,即使是像 LINE 和 Facebook 那样的同一台设备。我怎样才能做到这一点?我不想让别人知道发送到我的网络服务的任何参数。
我的后端服务器使用 google 云平台计算引擎。
编辑:我使用 Letsencrypt.org SSL 证书。
代码:
我的自定义请求
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 攻击。*
您的设备主要接受 2 种类型的证书:由 Verisign 或 Thawte 等可信组织颁发的证书,以及您自己安装的证书。
我怀疑 Packet Capture(如果您正在使用它)正在设备上安装自己的证书以使其受信任,稍后能够在传出连接上欺骗任何证书。
好消息是来自外部的任何 mitm 攻击都不会那么容易地做同样的事情。 (在某些情况下仍然有可能,例如出于可疑原因说服您安装应用程序或证书)。
要完全防止这种情况,您可以使用 certificate pinning 来确保您的连接不会被其他证书重新加密。
您还应该尝试从您的设备外部进行中间人攻击,例如使用 Charles 之类的代理来有效地查看您的连接是否仍然安全。
*:SSL不能保证证书和域名之间的link。它只保证签署连接的人应该是可信。 (要与一大块盐一起服用。任何人都可以购买几乎不需要验证的证书。)
我正在开发 android 应用程序并使用 SSL 连接连接到我的服务器。
为了连接到我的网络服务,我使用 Volley Request 到我的服务器 https 地址。
但是,当我尝试使用 Packet Capture 拦截我的连接时,它使用 man in the middle 方法来拦截我的连接,它看起来像一个非 SSL 连接。我可以看到整个请求和响应。 但是,其他应用程序如 LINE、Facebook 无法通过 Packet Capture 解密。我想保护我的网络服务,即使是像 LINE 和 Facebook 那样的同一台设备。我怎样才能做到这一点?我不想让别人知道发送到我的网络服务的任何参数。
我的后端服务器使用 google 云平台计算引擎。
编辑:我使用 Letsencrypt.org SSL 证书。
代码:
我的自定义请求
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 攻击。*
您的设备主要接受 2 种类型的证书:由 Verisign 或 Thawte 等可信组织颁发的证书,以及您自己安装的证书。
我怀疑 Packet Capture(如果您正在使用它)正在设备上安装自己的证书以使其受信任,稍后能够在传出连接上欺骗任何证书。
好消息是来自外部的任何 mitm 攻击都不会那么容易地做同样的事情。 (在某些情况下仍然有可能,例如出于可疑原因说服您安装应用程序或证书)。
要完全防止这种情况,您可以使用 certificate pinning 来确保您的连接不会被其他证书重新加密。
您还应该尝试从您的设备外部进行中间人攻击,例如使用 Charles 之类的代理来有效地查看您的连接是否仍然安全。
*:SSL不能保证证书和域名之间的link。它只保证签署连接的人应该是可信。 (要与一大块盐一起服用。任何人都可以购买几乎不需要验证的证书。)