API Security

Overview

AgriSmart will provide you with a Key ID and a Secret. You’ll use the secret to construct a SHA256 HMAC digest of the parameters to the API for each call.

SSL Required

Calls to the API must be made using SSL. Any non-SSL calls will be rejected.

Secret

The production secret we provide you must be kept secure. This secret is never transmitted across the wire and should be treated like a private key. Anyone who has access to your Key ID and Secret can make calls to our API on your behalf.

Sample C# Code

Here is a simplistic sample C# client that can call any of our APIs:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace JobAPITest
{
                class Client
                {
                                public const bool DEV = true;

                                public string KeyID { get; set; }
                                public string Secret { get; set; }
                                public string Path { get; set; }
                                public string Method { get; set; }
                                public string Body { get; set; }
                                public SortedDictionary<string, string> Parameters { get; private set; }

                                public Client()
                                {
                                                Method = "GET";
                                                Parameters = new SortedDictionary<string, string>();
                                }

                                public string MakeRequest()
                                {
                                                DateTime d = DateTime.Now.ToUniversalTime();
                                                string ds = d.ToString("yyyyMMddHHmmss'Z'");

                                                Debug.WriteLine(KeyID);
                                                Debug.WriteLine(ds);

                                                byte[] secretBytes = Encoding.UTF8.GetBytes(Secret);
                                                byte[] contentBytes = Encoding.UTF8.GetBytes(KeyID);

                                                HMACSHA256 sha256 = new HMACSHA256(secretBytes);
                                                byte[] keyBytes = sha256.ComputeHash(contentBytes);

                                                contentBytes = Encoding.UTF8.GetBytes(ds);
                                                sha256 = new HMACSHA256(keyBytes);
                                                keyBytes = sha256.ComputeHash(contentBytes);

                                                foreach (var item in Parameters)
                                                {
                                                                contentBytes = Encoding.UTF8.GetBytes(item.Value);
                                                                sha256 = new HMACSHA256(keyBytes);
                                                                keyBytes = sha256.ComputeHash(contentBytes);
                                                }

                                                if ("GET" != Method)
                                                {
                                                                contentBytes = Encoding.UTF8.GetBytes(Body);
                                                                sha256 = new HMACSHA256(keyBytes);
                                                                keyBytes = sha256.ComputeHash(contentBytes);
                                                }

                                                contentBytes = Encoding.UTF8.GetBytes(Path);
                                                sha256 = new HMACSHA256(keyBytes);
                                                keyBytes = sha256.ComputeHash(contentBytes);

                                                StringBuilder sb = new StringBuilder();
                                                foreach (byte b in keyBytes)
                                                {
                                                                sb.AppendFormat("{0:x2}", b);
                                                }

                                                Debug.WriteLine(sb.ToString());

                                                StringBuilder urlBuilder = new StringBuilder();
                                                string baseUrl = "https://staging.agrismartis.com";
                                                if (DEV) baseUrl = "http://localdev.agrismartis.com:3000";

                                                urlBuilder.AppendFormat("{0}{1}?kid={2}&date={3}&key={4}",
                                                                baseUrl,
                                                                Path,
                                                                KeyID,
                                                                ds,
                                                                sb.ToString()
                                                );

                                                if("GET" == Method)
                                                {
                                                                foreach(var item in Parameters)
                                                                {
                                                                                urlBuilder.AppendFormat("&{0}={1}", item.Key, item.Value);
                                                                }
                                                }

                                                string url = urlBuilder.ToString();
                                                Debug.WriteLine(url);

                                                HttpWebRequest wr = WebRequest.CreateHttp(url);
                                                wr.Method = Method;

                                                if("GET" != Method)
                                                {
                                                                wr.ContentType = "application/json";

                                                                Debug.WriteLine(Body);

                                                                byte[] formBytes = Encoding.UTF8.GetBytes(Body);

                                                                wr.ContentLength = formBytes.Length;

                                                                Stream requestStream = wr.GetRequestStream();
                                                                requestStream.Write(formBytes, 0, formBytes.Length);
                                                                requestStream.Close();
                                                }

                                                HttpWebResponse resp = null;

                                                try
                                                {
                                                                resp = (HttpWebResponse)wr.GetResponse();
                                                }
                                                catch (WebException ex)
                                                {
                                                                resp = (HttpWebResponse)ex.Response;
                                                }

                                                StreamReader sr = new StreamReader(resp.GetResponseStream());
                                                string body = sr.ReadToEnd();

                                                Debug.WriteLine(url);
                                                Debug.WriteLine(body);

                                                return body.Replace("\n", "\r\n");
                                }

                }
}

This client can be used to call the POST method of the Jobs API like so:

Client client = new Client();
client.KeyID = KeyID;
client.Secret = Secret;
client.Path = "/api/jobs";
client.Method = "POST";
client.Body = requestTextBox.Text.Trim();

resultsTextBox.Text = client.MakeRequest();