分享

怎样创建安全的Rest WebService API 请求

 richsky 2012-04-22
API Key

当用户注册之后,会给用户一个API Key。这个API Key会附在每个请求的url后面,这个方式的缺点是如果某个人知道你的API Key之后,他就能伪装成那个用户了。 但是如果你的API请求是使用HTTPS(SSL)的方式,就可以避免你的API Key被别人获取了。


API Key + Secret Key签名

比上一种跟复杂的一种方式就是用一个secret key去签名每一刻API URL请求,Amazon Web Services就是使用这种方式。当用户注册完后, 你会给用户2个keys:API Key(比如:username)和secret key(比如password),API key会附在每个请求url上面,但是secret key
不会。secret key是用来签名每个请求的。通常会加上另外一个参数比如(Signature)。

Amazon会把所有的请求信息作为请求的参数,然后按照参数名排序,再按照secret key进行hash。这个hash的值会作为一个新的参数(Signature)附加到请求的url上。在server端做相同的事情,获得所有的参数(除了Signature),排序,用sercet key hash,如果这个值跟传过来的Signature参数的值相等的话,则认为这个请求是合法的。



下面的是引用Amazon Web Services文档中的内容。

For example, the following is a Query string (linebreaks added for clarity).

引用
Action=DescribeImages
&AWSAccessKeyId=10QMXFEV71ZS32XQFTR2
&SignatureVersion=1
&Timestamp=2006-12-08T07%3A48%3A03Z
&Version=2007-01-03


For the preceding Query string, you would calculate the HMAC signature over the following string.
引用
(linebreaks added for clarity)
      ActionDescribeImages
      AWSAccessKeyId10QMXFEV71ZS32XQFTR2
      SignatureVersion1
      Timestamp2006-12-08T07:48:03Z
      Version2007-01-03


Using the preceding string and the secret key DMADSSfPfdaDjbK+RRUhS/aDrjsiZadgAUm8gRU2 the
base64 encoded signature is as follows:
GjH3941IBe6qsgQu+k7FpCJjpnc=

The following is a Java code sample to compute the signature from the string and the private key.

引用
import java.security.SignatureException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class HmacExample
{
    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
/**
* Computes RFC 2104-compliant HMAC signature.
     *
     * @param data
     *     The data to be signed.
     * @param key
     *     The signing key.
     * @return
     *     The base64-encoded RFC 2104-compliant HMAC signature.
     * @throws
     *     java.security.SignatureException when signature generation fails
     */
    public static String calculateRFC2104HMAC(String data, String key)
          throws java.security.SignatureException
    {
       String result;
       
        try {
            // get an hmac_sha1 key from the raw key bytes
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(),
             HMAC_SHA1_ALGORITHM);
            // get an hmac_sha1 Mac instance
            // and initialize with the signing key
            Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
            mac.init(signingKey);
            // compute the hmac on input data bytes
            byte[] rawHmac = mac.doFinal(data.getBytes());
            // base64-encode the hmac
            result = Base64.encodeBytes(rawHmac);
        }
        catch (Exception e) {
            throw new SignatureException("Failed to generate HMAC : "
                + e.getMessage());
        }
       
     return result;
     }
       
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多