2. Authentication parameter algorithm
4. Authorization generation example - Python
5. Authorization generation example -Java
To improve API access security, the authorization parameterAuthorizationof OneNET API is taken as a Header parameter.
The core key calculated by Authorization is accessKey. The user needs to calculate the signature using the core key adopting signature algorithm, and form the authentication parameter together with other parameters, and then perform authentication using the authentication parameter Authorization as the request header parameter.
The authentication security is improved by avoiding the direct transmission of the core key on the network, increasing the time control of authentication parameters and strengthening key authority granularity control (upcoming), so as to maximum access security.
GET /devices/35****92 //35****92 device ID randomly assigned by the onenet
Authorization: version=2018-10-31&res=products%2F123123&et=1537255523&method=sha1&sign=ZjA1NzZlMmMxYzIOTg3MjBzNjYTI2MjA4Yw%3D
Name | Type | Required or not | Parameter Description | Parameter Example |
---|---|---|---|---|
version | string | Yes | Parameter group version No. is in date format, currently using “2018-10-31”. | 2018-10-31 |
res | string | Yes | Access resources resource Format: Parent resource class/parent resource ID/ child resource class/ child resource ID Please refer to res usage scenario description after the table. | products/123123 products/123123/devices/78329710 mqs/osndf09nand9f21390 |
et | int | Yes | Access expiration timeexpirationTime() ,is expressed in unix time. When the et time in an access parameter is earlier than the current time, the access parameter is considered expired and the access is refused. | 1537255523 represents: Beijing Time 2018-09-18 15:25:23 |
method | string | Yes | Signature method(signatureMethod) supportsmd5、sha1、sha256 | sha256 |
sign | string | Yes | Signature result string signature |
Scenario | res Parameter Format | Examples | explain |
---|---|---|---|
API Access | products/{pid} | products/123123 | |
Device Connection | products/{pid}/devices/{device_name} | products/123123/devices/mydev | require device' s access-key |
(2) StringForSignature is constituted as follows:
Note:The format of each parameter is key=value, but only the value in the parameter is used in the composition of the string of StringForSignature for calculating the signature.
et = 1537255523
method = sha1
res = products/123123
version = 2018-10-31
(2)The string of StringForSignature used for calculating the signature is (following the sequence of et, method, res and version).
StringForSignature = "1537255523" + "\n" + "sha1"+ "\n" + "products/123123"+ "\n" + "2018-10-31"
(3)After sign is calculated, each parameter is expressed in the form of key=value with “&” as the separator. An example is given below:
version=2018-10-31&res=products/123123&et=1537255523&method=sha1&sign=ZjA1NzZlMmMxYzIOTg3MjBzNjYTI2MjA4Yw=
No. | Symbol | Encode |
---|---|---|
1 | + | %2B |
2 | Space | %20 |
3 | / | %2F |
4 | ? | %3F |
5 | % | %25 |
6 | # | %23 |
7 | & | %26 |
8 | = | %3D |
After encoding, the Authorization actually transmitted in above example is:
version=2018-10-31&res=products%2F123123&et=1537255523&method=sha1&sign=ZjA1NzZlMmMxYzIOTg3MjBzNjYTI2MjA4Yw%3D
!!!The token in the code here is the Authorization.
import base64
import hmac
import time
from urllib.parse import quote
def token(id,access_key):
version = '2018-10-31'
res = 'products/%s' % id # access to product API by product ID
# user-defined token expiration time
et = str(int(time.time()) + 3600)
# signature method,supports md5、sha1、sha256
method = 'sha1'
# decode access_key
key = base64.b64decode(access_key)
# calculate sign
org = et + '\n' + method + '\n' + res + '\n' + version
sign_b = hmac.new(key=key, msg=org.encode(), digestmod=method)
sign = base64.b64encode(sign_b.digest()).decode()
# the value part is URL encoded, and the method/res/version value is relatively simple, with no coding required
sign = quote(sign, safe='')
res = quote(res, safe='')
# token parameters are concatenated
token = 'version=%s&res=%s&et=%s&method=%s&sign=%s' % (version, res, et, method, sign)
return token
if __name__ == '__main__':
id = '123123'
access_key = 'KuF3NT/jUBJ62LNBB/A8XZA9CqS3Cu79B/ABmfA1UCw='
print(token(id,access_key))
!!!The token in the code here is the Authorization.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class Token {
public static String assembleToken(String version, String resourceName, String expirationTime, String signatureMethod, String accessKey)
throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
StringBuilder sb = new StringBuilder();
String res = URLEncoder.encode(resourceName, "UTF-8");
String sig = URLEncoder.encode(generatorSignature(version, resourceName, expirationTime
, accessKey, signatureMethod), "UTF-8");
sb.append("version=")
.append(version)
.append("&res=")
.append(res)
.append("&et=")
.append(expirationTime)
.append("&method=")
.append(signatureMethod)
.append("&sign=")
.append(sig);
return sb.toString();
}
public static String generatorSignature(String version, String resourceName, String expirationTime, String accessKey, String signatureMethod)
throws NoSuchAlgorithmException, InvalidKeyException {
String encryptText = expirationTime + "\n" + signatureMethod + "\n" + resourceName + "\n" + version;
String signature;
byte[] bytes = HmacEncrypt(encryptText, accessKey, signatureMethod);
signature = Base64.getEncoder().encodeToString(bytes);
return signature;
}
public static byte[] HmacEncrypt(String data, String key, String signatureMethod)
throws NoSuchAlgorithmException, InvalidKeyException {
//construct a secret key from the given byte array,and the second parameter specifies a key algorithm
SecretKeySpec signinKey = null;
signinKey = new SecretKeySpec(Base64.getDecoder().decode(key),
"Hmac" + signatureMethod.toUpperCase());
//generate a Mac object for th specified Mac algorithm
Mac mac = null;
mac = Mac.getInstance("Hmac" + signatureMethod.toUpperCase());
//initialize the Mac object with the given key
mac.init(signinKey);
//Mac operation is finished
return mac.doFinal(data.getBytes());
}
public enum SignatureMethod {
SHA1, MD5, SHA256;
}
public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
String version = "2018-10-31";
String resourceName = "products/123123";
String expirationTime = System.currentTimeMillis() / 1000 + 100 * 24 * 60 * 60 + "";
String signatureMethod = SignatureMethod.SHA1.name().toLowerCase();
String accessKey = "KuF3NT/jUBJ62LNBB/A8XZA9CqS3Cu79B/ABmfA1UCw=";
String token = assembleToken(version, resourceName, expirationTime, signatureMethod, accessKey);
System.out.println("Authorization:" + token);
}
}