iPEK License API - v.1.0
Basics
All request and responses described in this document are encrypted - information's about algorithm can be found at the bottom of the page
Endpoints
Note: All request uses the same model, described in the next section - the only difference is in a Type
field in the request and in the extra fields in request/response
Pre-prod: https://pre.beta.wincan.com/licensing/api
Prod: https://web.wincan.com/licensing/api
Endpoint | Method | Type field | Additional request field | Additional response field | Additional response field | Content-Type header |
---|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
| " |
|
|
|
|
|
|
|
|
Request
|
Email of end-user
|
requestId
, sessionId
, hardwareId
are GUIDs.
Response
|
|
PoSSIBLE HTTP Responses
Code | Name | Returns data? | Remarks |
---|---|---|---|
|
| Yes | used for status ERROR too |
|
| No |
|
|
| No |
|
Errors
Common
validation_error
unsupported_api_version
unsupported_product
Activation
invalid_code
already_activated
license_expired
license_deleted
Deactivation
wrong_number
Check
not_activated
wrong_number
license_deleted
Authorization
We are using the HMAC SHA256 authorization. Server and client have the same SECRET (need to calculate signature, see below).
Creating authorization headers steps:
Header name | Description | Example |
---|---|---|
Date | Current date in UTC format. You need it to create representation string. IMPORTANT! Date should be synchronized with our servers! Current date you can get from GET webapi/Status/Get PRE - https://pre.beta.wincan.com/licensing/api/webapi/Status/Get PROD- https://web.wincan.com/licensing/api/webapi/Status/Get
The best approach is to get current date from server when you run your app, count the offset between application current date and Wincan Service date and add this offset to current date when you send request to Wincan Service | Wed, 04 Mar 2015 09:38:51 GMT |
Authorization | Authorization Scheme - constant string “WincanLicenseService“ Signature - it is calculation of secret key and representation string See below | WincanLicenseService LUR9P9zv5WsUAu/OXPKflGoVDPgalBIsXmfAnidZW5k= |
X-WinCanLicenseService-MessageToken | Random token. Can be guid. You need it to create representation string | 5f57e08a-bdc4-4c78-9798-d31685851ecd |
X-WinCanLicenseService-ClientId | The name of client. You need it to create representation string constant string “IPEK“ | IPEK |
Authorization - Signature
Signature it is a calculation of secret key and representation string.
To genereate this signature we are using method like:
public string Generate(string secret, string representation)
{
var secretBytes = Encoding.UTF8.GetBytes(secret);
var valueBytes = Encoding.UTF8.GetBytes(value);
string signature;
using (var hmac = new HMACSHA256(secretBytes))
{
var hash = hmac.ComputeHash(valueBytes);
signature = Convert.ToBase64String(hash);
}
return signature;
} |
---|
Authorization - How to generate representation string?
The representation string should be in format like:
METHOD\n
UtcDateString\n
MessageToken\n
ClientId\n
AbsoluteUrl
where:
Representation part | Description | Example |
---|---|---|
METHOD | The rest method | PUT |
UtcDateString | Current date in UTC format. This value should be the same which is in header in Date | Wed, 04 Mar 2015 09:38:51 GMT |
MessageToken | Random token. Can be guid. This value should be the same which is in header in X-WinCanLicensingService-MessageToken | 5f57e08a-bdc4-4c78-9798-d31685851ecd |
ClientId | The name of client. This value should be the same which is in header in X-WinCanLicensingService-ClientId | IPEK |
AbsoluteUrl | The absolute url from request. (Without query string and /api/ prefix) | ipek/activate |
It is important to split data by sign \n
Example:
Body encryption - Implementation samples
You can check out a working sample of the application [SAMPLE_APP_NAME] (C#).
Sample implementation:
|
Body encryption
To encode request body, we need following things:
RSA CSP public key (private belongs to the licensing server)
AES 256-bit - new for each request
Encode body steps:
Generate new AES
Encode body with AES and convert to Base64 string
var body_encoded = ToBase64Str(aes.Encode(body))
AES IV convert to Base64, next encrypt IV parameter using RSA (encryption using OAEP padding) and convert it to Base64 string again:
var iv_base64str = ToBase64Str(aes.iv)
var iv_str = ToBase64Str(rsa.Encode(iv_base64str))
Do the same for Key parameter
var key_base64str = ToBase64Str(aes.key)
var key_str = ToBase64Str(rsa.Encode(key_base64str))
Create message
var result = iv_str + "|" + key_str + "|" + body_encoded
To decode response body, we need following things:
RSA CSP private key (public is used by the licensing server, it is a different one than the key used during request encryption)
Decode body steps:
Split message on 3 parts, using "
|
" character (the same format as in the request)ASDOASKD234=|2ASD+2fDSF=|asdasdasd...
First part is IV parameter of AES, second part is Key parameter of AES. We have to convert them from Base64 to bytes and then decode them using RSA private key
Now we can use generated AES to decode third part of body, which is an appropriate response