POST请求的安全性

时间:2018-08-23 01:00:56

标签: java http security post https

我最近实现了一些代码,这些代码基本上将POST请求发送到站点,并且出于安全原因,它们要求使用SHA256对sigToEncrypt字符串进行加密。我已经进行了测试,并且对我打算使用的以下代码功能充满信心;但是,我想确保它实际上是安全的,因为我对传输协议和相关主题还有些陌生。

try {

    URI uri;
    String sigToEncrypt;

    // I initialize the sigToEncrypt and uri here (omitting this for SO question)

    // I know this method works as intended
    String signature = generateHMACSHA256Signature(PRIVATE_KEY, sigToEncrypt);

    // Build signed URI w/ encrypted signature (need only for the 'toSend' String)
    URI uriSigned = new URIBuilder(uri).setParameter("signature", signature).build();

    // This is what we actually POST, includes the encrypted signature. Seems hack-y.
    String toSend = uriSigned.toString().substring(uriSigned.toString().indexOf('?') + 1);

    // Here we set up for the post request, specify encoding, public key, etc.
    HttpPost httppost = new HttpPost(POST_URL_STRING);
    httppost.setHeader(KEY_HEADER, PUBLIC_KEY);
    httppost.setHeader("Content-Type", CONTENT_TYPE + "; " + ENCODING);
    // This is the 'important part' of the POST request
    StringEntity se = new StringEntity(toSend);
    httppost.setEntity(se);

    // Make a client so that we can have something to execute our POST from.
    HttpClient client = HttpClients.createDefault();

    // Here's where we actually execute the post request.
    HttpResponse response = client.execute(httppost); 

    // This returns the result of the request. I know this method works and 
    // that the post was successful.
    result = parseServerResponse(response);

} catch (Exception e) {
    // Do stuff with errors, not pertinent to the question
}

这是我目前对这段代码的安全性的看法:

    乍一看,我认为我的信息是安全的,因为我们对签名进行了加密,因此如果没有私钥(只有在我的代码中才能找到),有人无法获得任何此类信息。
  1. 乍一看,我对使用HttpPost类犹豫不决,因为我知道http不是安全协议。但是,我要发送到的URL以https开头,所以也许我认为它毕竟是安全的(我真的不确定,关于此安全性和/或如何使其安全的任何帮助将不胜感激)。

  2. 最后,虽然少了思想,却多了询问,但是如果我的代码不能安全地发送POST请求,是否有可以使其安全的api?我找了一会儿,似乎没找到不符合要求的东西,就找不到真正适合我需要的东西,所以我很高兴听到你们有任何建议。

  3. 最后,即使我的代码是安全的,我似乎总是看到SO上的人们使用软件包/ api来执行他们本来不想做的事情,或者从未进行过更新的工作,等等。以上可能就是这种情况代码,但是我想以“正确”的方式执行此操作,因此,如果可以将我当前的方法换成更轻松,更“不错”的POST方法,那我将不胜枚举。

一如既往,我感谢所有帮助,如果您需要澄清,请发表评论/问题,我应该能够提供。谢谢!

1 个答案:

答案 0 :(得分:1)

我将从尝试确定真正的要求开始-他们要求像他们这样的加密声音,也许不确定一开始他们想要达到什么目标:)

他们是要对信息进行加密以保护信息不被看到还是要对信息签名以保护信息不被篡改?您似乎正在加密某些签名-不知道这意味着什么,这样做的动机是什么。

问题2-HttpPost类引用HTTP协议。它与SSL / TLS层无关-这是与HTTP分离的一层。因此,将其发布到https://网址将使用SSL / TLS。要注意的事情-有效的证书,正确的TLS配置(如果端点面向互联网,则使用SSL Labs测试其配置。

问题4-IMHO在代码中实现此目标毫无意义-通过使用https://可以轻松实现传输安全-如果您还需要身份验证,则可以使用客户端证书。

顺便说一句,我有点想念为什么您要构建看起来像查询字符串的东西:

// Build signed URI w/ encrypted signature (need only for the 'toSend' String)
URI uriSigned = new URIBuilder(uri).setParameter("signature", signature).build();

// This is what we actually POST, includes the encrypted signature. Seems hack-y.
String toSend = uriSigned.toString().substring(uriSigned.toString().indexOf('?') + 1);

不确定Content-Type是什么,但是恕我直言,您可以将此内容发布为application/json或任何其他适合您的内容。如果您想将其发布为text/plainapplication/x-www-form-urlencoded,则可以执行以下操作:

您可以使用它代替我提到的代码,它会执行与现在相同的操作:

StringEntity se = new StringEntity("signature=" + URLEncoder.encode(signature, ENCODING));

这是

POST / HTTP/1.1
Key-Header: public_key_here
Content-Type: application/something; utf8
Content-Length: 19
Host: 127.0.0.1
User-Agent: Apache-HttpClient/4.5.6
Accept-Encoding: gzip,deflate
Connection: close

signature=signature

那很好用-我说这取决于服务器(另一端)以及它期望的Content-Type