Overview of JSON Signing and Encryption

EmpowerID’s REST-based APIs support the arbitrary signing and encryption of JSON content using the JSON Web Signature standard.

Controller actions designated with any one of [JsonWebSignature], [JsonWebEncryption], and [JsonWebSignatureEncryption] attributes and hosted in EmpowerID are assumed to support JSON signing and/or encryption.

  • The [JsonWebSignature] attribute signifies JSON signing only.
  • The [JsonWebEncryption] attribute signifies JSON encryption only.
  • The [JsonWebSignatureEncryption] attribute signifies JSON signing and encryption.

A controller action MAY NOT be decorated with more than one of above attributes.

JSON Web Signature

A controller action expecting signed JSON requests should be decorated with the [JsonWebSignature] attribute in addition to any other action related attributes. The default api controller template in Workflow Studio includes an action decorated with this attribute.

[JsonWebSignature]
[HttpPost]
public IHttpActionResult GetUserJWS(InputModel model)
{
	var results = <results>;

	return this.Json((object)results);
}

To execute the above action, GetUserJWS, successfully, the api request must be signed using the private key of the X509 certificate associated with the OAuth Provider Application in EmpowerID. An OAuth Provider Application in EmpowerID is typically identified by the APIKey specified in the header of the request. You may also override the GetJwsVerifyCertificate method in the api controller to ignore the certificate associated with the OAuth Provider Application and return a preferred certificate for the same purpose. The Workflow Studio API controller template generates the methods you may override.

public override X509Certificate2 GetJwsVerifyCertificate(System.Web.Http.Controllers.HttpActionContext actionContext)
{
	//TODO: Resolve JWS request verify certificate
	return null;
}
public override X509Certificate2 GetJwsSigningCertificate(System.Web.Http.Controllers.HttpActionContext actionContext)
{
	//TODO: Resolve JWS response signing certificate
	return null;
}


Signing an API request

To sign an API request, call the Sign() static method on the TheDotNetFactory.Framework.JWS class and pass the JSON data and the X509 certificate. The sample code below assumes that the action, getuserjws, is decorated with the [JsonWebSignature] attribute.

The private key certificate is required to sign the JSON data passed to the Sign() method.

Client-side / Sender
X509Certificate2 signing = <your signing certificate>
string url = https://demoserver/api/ services/v1/Users/getuserjws;
string data = JWS.Sign(json, signing);
using (WebClient client = new WebClient())
{
	byte[] str = System.Text.Encoding.UTF8.GetBytes(data);
	byte[] results = client.UploadData(url, "POST", str);
	if (results != null)
		return System.Text.Encoding.UTF8.GetString(results);
	else
	return null;
}
Server-side / Action
[JsonWebSignature]
[HttpPost]
public IHttpActionResult GetUserJWS(InputModel model)
{
	var results = <results>;

	//JWS response
	return this.Json((object)results);
}


Encrypting an API request

To encrypt an API request, you can call the Jose.JWT.Encode() static method. The sample code below assumes that the action, getuserjwe, is decorated with the [JsonWebEncryption] attribute.

Client-side / Sender
JweAlgorithm alg = … //Specifies the encryption algorithm
JweEncryption enc = … //Specifies the encryption key size
byte[] toEncryptionKey = … //Specifies the encryption key
string url = https://demoserver/api/ services/v1/Users/getuserjwe;
string data = JWT.Encode(json, toEncryptionKey, alg, enc);
using (WebClient client = new WebClient())
{
	byte[] str = System.Text.Encoding.UTF8.GetBytes(data);
	byte[] results = client.UploadData(url, " POST", str);
	if (results != null)
		return System.Text.Encoding.UTF8.GetString(results);
	else
	return null;
}
Server-side / Action
[JsonWebEncryption(JweAlgorithm.A256KW, JweEncryption.A128CBC_HS256)]
[HttpPost]
public IHttpActionResult GetUserJWE(InputModel model)
{
	var results = <results>;

	//JWE response
	return this.Json((object)results);
}


Please note that the Jose.JWT.Decode() static method is called to decrypt the encrypted payload in an encrypted request, therefore, it is important that the encryption algorithm, encryption key, and the encryption key size are all correct and consistent with that of the sender. You must override the GetJWEDecryptionKey() method in the controller to return the encryption key. See the override method below.

public override byte[] GetJWEDecryptionKey(HttpActionContext actionContext)
{
	return ApiControllerBase.DEFAULT_ENCRYPTIONK_KEY;
}


For a walkthrough that demonstrates how to use JSON encryption and signing in EmpowerID, see the walkthrough on JSON Signing and Encryption.

On this page