Implementing End to End Restful Web API Encryption with SHA512




This tutorial teaches how you can implement custom security using SHA512 encrypting algorithm to make an end to end data encryption in web APIs. 

In the end, you will be able to enforce data integrity over the web APIs.


Overview
This tutorial simulates sending a sample payment request to the server for processing.

In the tutorial we will:
  • Create a Payment Model
  • Create Encryption Engine
  • Add Payment API Controller
  • Call the Payment API with Postman


Design Model
The following diagram shows the design model:






Prerequisites 
  • Visual Studio 2019, 2017, 2015, 2012 with the ASP.NET and Web development workload.


Create Payment Model
  • Create a new web API project and name the project WebAPIEnd2EndEncryption.
  • Right-click the Models folder and select Add > Class. Name the class Payment and select Add.
  • Replace the template code with the following:
   namespace WebAPIEnd2EndEncryption.Models
{
    public class Payment
    {
        public int ReferenceID { get; set; }
        public string CustomerName { get; set; }
        public decimal TotalAmount { get; set; }
        public string PhoneNumber { get; set; }
        public string Currency { get; set; }
        public string TransReference { get; set; }
        public string Hash { get; set; }
    }
}

  

Create Encryption Engine
  • In Solution Explorer, right-click the project. Select Add > New Folder. Name the folder SHA512EncryptionEngine.
  • Right-click the SHA512EncryptionEngine and select Add >Class. Name the class EncryptionHelper.
  • Replace The template code with the following code:
using System.Security.Cryptography;

namespace WebAPIEnd2EndEncryption.SHA512EncryptionEngine
{
    public static class EncryptionHelper
    {
        const string HashSalt= "d0k8hRzrjRkWOVLd28fwpDZlrm1Vuv3eoyEhzJeBIVpXbInxkoSOr5qZWRFINjsl7SVyW1hdVZ5dbJKmOu9Bibcv8qFIxs5hvgKvTReEggMlmByVBMdzKvSuDwtwscG9mKuSt505ulVPD6GcbYDrcZ"; 
        public static string EncryptSha512(string value)
        {
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            byte[] keyByte = encoding.GetBytes(HashSalt);
            HMACSHA512 hMACSHA = new HMACSHA512(keyByte);

            byte[] messageBytes = encoding.GetBytes(value);
            byte[] hashmessage = hMACSHA.ComputeHash(messageBytes);

            return ByteToString(hashmessage);
        }

        private static string ByteToString(byte[] buff)
        {
            string sbinary = "";

            for (int i = 0; i < buff.Length; i++)
            {
                sbinary += buff[i].ToString("X2"); // hex format
            }
            return (sbinary);
        }
    }
}


The preceding code:
  • Declares a constant HASHSALT value to be used by both the API and the client end for encryption.
  • Adds EncryptSha512 method. The method takes a string parameter and computes hash using HMACSHA512 and HASHSALT as key.
  • Adds ByteToString which converts the resulting hash to Hexadecimal format.

The code above implements the encryption engine at the API end. Later in the tutorial, Postman will be used as a client to call the Payment API. Thus, at the client end, the encryption engine can be implemented like so:

const HASHSALT="d0k8hRzrjRkWOVLd28fwpDZlrm1Vuv3eoyEhzJeBIVpXbInxkoSOr5qZWRFINjsl7SVyW1hdVZ5dbJKmOu9Bibcv8qFIxs5hvgKvTReEggMlmByVBMdzKvSuDwtwscG9mKuSt505ulVPD6GcbYDrcZ"

var rawValue="Value to be hashed";

pm.environment.set("hash",CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA512(rawValue, HASHSALT)));


Add Payment API Controller
  • In Solution Explorer, right-click the controllers folder. Select Add > Controller > Web API Controller-Empty. Name the controller Payment and select add.
  • Replace the template code with the following:

using System;
using System.Net.Http;
using System.Web.Http;
using WebAPIEnd2EndEncryption.Models;
using WebAPIEnd2EndEncryption.SHA512EncryptionEngine;

namespace WebAPIEnd2EndEncryption.Controllers
{
    public class PaymentController : ApiController
    {
        [HttpGet]
        public HttpResponseMessage GetPayment()
        {
            return Request.CreateResponse(new
            {
                error = false,
                message = "Payments"
            });
        }
        [HttpPost]
        public HttpResponseMessage PostPayment([FromBody]Payment payment)
        {
            try
            {
                if (payment == null) return Request.CreateResponse(new
                {
                    error = true,
                    message = "Bad Request"
                });

                string rawValue = $"{payment.TotalAmount}{payment.Currency}{payment.TransReference}";
                string computeHash = EncryptionHelper.EncryptSha512(rawValue);
                if (payment.Hash.ToLower() != computeHash.ToLower()) return Request.CreateResponse(new
                {
                    error = true,
                    message = "Invalid hash detected"
                });

                return Request.CreateResponse(new
                {
                    error = false,
                    message = "Payment Processed successfully"
                });
            }
            catch (Exception)
            {
                return Request.CreateResponse(new
                {
                    error = true,
                    message = "Error occured while processing your request"
                });
            }
        }
    }
}

The preceding code:
  • Declares GePayment method which returns a dummy message to the client
  • Adds PostPayment method. This method expects payment model from the request body. If the payment model in the client request in null, then Bad Request returns as a message with error status true:
  • Concatenates some of the payment model parameter to be hashed. In this case, TotalAmount, Currency, and TransReference respectively.
  • Computes the hash value and compares it with the computed hash value sent by the client.       
  • Checks if the computed hash is the same with the hash sent by the client, and returns Invalid hash detected as a message with error status true if the hash does not match.

Call the Payment API using Postman as Client
  • Install Postman if it’s not already installed on your computer
  • Start Postman
  • Run the application
  • Create a new Get request to test the API, set the HTTP method to Get and the request URL to https://localhost:<port>/api/payment.
  • Select Send.


  • Create a new POST request.
  • Edit the Pre-request Script like so:


  • Edit the body and select Send like so:




I hope the write up is helpful. Please don't forget to drop your comments and remarks.

Download the complete source code from here.
Implementing End to End Restful Web API Encryption with SHA512 Implementing End to End Restful Web API Encryption with SHA512 Reviewed by Akintunde Toba on September 07, 2019 Rating: 5

No comments:

Home Ads

Powered by Blogger.