我正在开发REST webService,我的一些客户端将使用我的web服务,因此为了识别真正的客户端,我决定给每个真正的客户端一个唯一的应用程序令牌。客户端将对此令牌进行编码,他们会将此令牌放入请求标头中,并且我已在REST Web服务中配置REST过滤器以验证令牌。我不想使用https。我的问题是,任何人都可以从我的客户端站点获取该令牌,并可以使用我的REST Web服务。我怎么能阻止这个?
答案 0 :(得分:1)
由于您不想使用https,我认为机密性不是问题,您只想基于谁制作请求来授权请求。您应该要求您的客户签署他们的请求,而不是传递可能被盗的普通令牌。你在这里有一个很好的解释:
简而言之,取自Implementing HMAC authentication for REST API with Spring Security:
该逻辑可以使用任何编程语言实现。以下是java中的伪代码签名示例:
//clientId is the public client identifier
//secretKey is the key shared between server and client
//requestContent is a string representation of the HTTP request (HTTP verb, body, etc.
//init signing key and mac
SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
//sign the request content
byte[] rawHmac = mac.doFinal(requestContent.getBytes());
//encode to base64
String result = base64(rawHmac);
//store in header
request.setHeader("Authorization", "MyAPI " + clientId + ":" + result);
在服务器端,当您收到该请求时,从头中提取clientId和签名,检索与收到的clientId对应的密钥,重新计算签名(完全如上)并比较结果。它匹配客户端是否被授权,如果不是你返回HTTP 403(或任何你想要的错误)。
然后没有更多的“秘密”可以窃取中间的潜在人,但是仍然需要在客户端和服务器上安全地存储密钥。泄漏这些密钥会损害整个系统。
答案 1 :(得分:0)
由于令牌无法在HTTP层安全传输,因此可以轻松获取此令牌。您可以通过组合一些具有时间戳的逻辑来让真正的客户端加密此令牌,以便每次使用某种不同的算法加密令牌时,在服务器端,您应该遵循类似的算法来解密它。这种方式即使有人拿到了无法重复使用的令牌。一种方法是使用Google身份验证器加入此加密逻辑。 (http://www.techrepublic.com/blog/google-in-the-enterprise/use-google-authenticator-to-securely-login-to-non-google-sites/)
答案 2 :(得分:0)
使用校验和来保护消息,如下所示
MD5或SHA1校验和应该用于验证密码而不传递实际密码。
The server sends a random string to the client.
The client appends his password to the random string, and returns an MD5/SHA1 sum of the result to the server.
On the server, do the same and compare the MD5/SHA1 sums.
If both MD5/SHA1 are identicals then the password is good and message is not changed.