itsgoingdown.org is very important when developing applications. How do you encrypt data and manage encryption keys in your application? Successful key is critical to the security of a cryptosystem. This is where KMS’s come into play. Let’s first see what a KMS really is. Security management Key Management System (KMS) According to Wikipedia, A (KMS), also known as a (CKMS), is an integrated approach for generating, distributing and managing for devices and applications. Compared to the term key management, a KMS is tailored to specific use-cases such as secure software update or communication. In an holistic approach, it covers all aspects of security — from the secure generation of keys over the secure exchange of keys up to secure key handling and storage on the client. Thus, a KMS includes the backend functionality for , distribution, and replacement as well as the client functionality for injecting keys, storing and managing keys on devices. With the , KMS becomes a crucial part for the security of connected devices. key management system crytographic key management system cryptographic keys machine-to-machine key generation Internet of Things A KMS makes your life easy when dealing with key management and encryption. AWS KMS Now we know what a key management system is. Let’s talk about AWS KMS briefly. AWS KMS is a service by AWS that makes it easy for you to manage your encryption keys. It uses Hardware Security Modules (HSMs) in the backend. AWS KMS is integrated with other AWS services. It is also low in cost. AWS KMS provides access control to your keys so that you can determine who can access the keys when can the keys be accessed and a lot of other options. AWS KMS uses the algorithm in , known as AES-GCM. AWS KMS uses this algorithm with 256-bit secret keys. Advanced Encryption Standard (AES) Galois/Counter Mode (GCM) AWS KMS pricing can be viewed . Free tier includes 20,000 requests/month. here Using AWS KMS With Node.js In this section I am going to share how to use AWS KMS within your Node.js application. I will cover the following topics here, How to create a CMK (Customer Master Key). How to attach an IAM user to CMK with an IP restricted policy. How to encrypt data using CMK. How to decrypt data using CMK. Envelope encryption using AWS KMS. Encryption context (Intro) With that being said I want to first state that I am not a crypto expert!. How to create a CMK (Customer Master Key) The primary resources in AWS KMS are (CMKs). CMKs are either customer managed or AWS managed. Let’s take a look at how to create a customer master key in AWS. customer master keys Login to AWS console and go to services. Then select “IAM”. There on the left side you can see a section called “Encryption Keys”. Navigate to that section. Then select “Create Key” on top left. Enter an alias for the key and a description. In the advanced options select KMS. Here you can import your own external key if you want. I am not going to cover how to import an external key here (It is also pretty straight forward). Click next. Add tags (optional) if you require. Go to next step again. If you have an IAM user already created (If not skip selecting a user. We will create a user later) and if you want to allow that user to access this key select the user from the list and click next. Finally finish the process. Your key will be created now. How to attach an IAM user to CMK with an IP restricted policy Now if you don’t have a previously created IAM user, follow these steps to create one. Go to “IAM” (as above). Select “Users” on the left side. Select “Add user” top left corner. Fill the required details. An example is given below. Select next. Select the option “Attach existing policies directly”. Then select “Create policy”. You can visually edit the policy or edit the json of the policy. I am going to edit the json here. Select “json” tab. I will be using the below simple policy which will only allow access to the CMK from a one selected IP. You can select an IP range or you can customize the policy in any way you want. After that follow the instructions to save the created policy. Then finish creating the user. At the last page new user’s Access key ID and Secret access key will be displayed. Download those information. You won’t be able to view it afterwards (But you can create new credentials again). Now go to Encryption keys and select the key that you just created. Go to “Key Users” section and select “Add”. Select the user you have created. Then that user will be added to the allowed list for the CMK you created. Key Users How to encrypt data using CMK Enough setting up things, let’s see how to use AWS KMS! I am using AWS SDK for Node.js here. Let’s install AWS SDK package from npm. npm install aws-sdk Following function encrypts a given buffer and outputs the cipher text blob. encrypt(buffer) { kms = aws.KMS({accessKeyId: 'AKCVBTRNOSMLTIA7RPQQ', //credentials for your IAM usersecretAccessKey: 'lJQtdIfH/Cup9AyaaHV8h2NnR/eKFIsZea5Vn0k', //credentials for your IAM userregion: 'ap-southeast-1'}); Promise((resolve, reject) => { params = {KeyId: '965d2884-b2cd-4d79-8773-6b1f57133300', // The identifier of the CMK to use for encryption. You can use the key ID or Amazon Resource Name (ARN) of the CMK, or the name or ARN of an alias that refers to the CMK.Plaintext: buffer// The data to encrypt.};kms.encrypt(params, (err, data) => { (err) {reject(err);} {resolve(data.CiphertextBlob);}});});} function const new return new const if else How to decrypt data using CMK Following function decrypts a cipher text blob that was encrypted before and returns the plain text buffer. decrypt(buffer) { kms = aws.KMS({accessKeyId: 'AKCVBTRNOSMLTIB7ROQQ',secretAccessKey: 'lJQtdIfH/Cup9AyabHV9h2NnR/eKFIsZea2Vn0k',region: 'ap-southeast-1'}); Promise((resolve, reject) => { params = {CiphertextBlob: buffer// The data to dencrypt.};kms.decrypt(params, (err, data) => { (err) {reject(err);} {resolve(data.Plaintext);}});});} function const new return new const if else Following code encrypts the text “abc” then decrypts it and prints the value to the console encrypt( Buffer('abc','utf-8')).then(decrypt).then(plaintext => {console.log(plaintext.toString('utf-8'));}); new Envelope encryption using AWS KMS AWS KMS has a size limit on directly encrypting data using the CMK. You can only encrypt up to 4 kilobytes of data per request. If you want to encrypt data of bigger size, for an example a video, you need to use envelope encryption. In envelope encryption we generate a data key by using our CMK at KMS. When generating the data key, AWS sends us both the plaintext key and the encrypted key (using our CMK). Then we use the plaintext data key generated to encrypt our data. After encrypting the data we destroy the plaintext key and keep the encrypted key with us. When we want to decrypt the data we send the encrypted key to AWS KMS and get back the plaintext key and continue with decryption. First we need to generate a data key from AWS KMS. Following diagram depicts that procedure. http://docs.aws.amazon.com Following function generates a data key from AWS KMS. generateDataKey() { kms = aws.KMS({accessKeyId: 'AKCVBTRNOSMLTIB7ROQQ',secretAccessKey: 'lJQtdIfH/Cup9AyabHV9h2NnR/eKFIsZea2Vn0k',region: 'ap-southeast-1'}); Promise((resolve, reject) => { params = {KeyId: '965d2884-b2ab-4e78-8773-6b1f57133300', // The identifier of the CMK to use to encrypt the data key. You can use the key ID or Amazon Resource Name (ARN) of the CMK, or the name or ARN of an alias that refers to the CMK.KeySpec: 'AES_256'// Specifies the type of data key to return.};kms.generateDataKey(params, (err, data) => { (err) {reject(err);} {resolve(data);}});});} function const new return new const if else “data” has both encrypted data key and plain text data key as buffers. Next step is encrypting data with plain text data key. http://docs.aws.amazon.com Following is an example code which uses AES-CBC to encrypt data using the data key. This uses crypto package. Here I have used a fixed iv (initialization vector) for the simplicity. encryptAES(key, buffer) { algorithm = 'AES-256-CBC'; function const **const** iv = **new** Buffer('00000000000000000000000000000000', 'hex'); encryptor = crypto.createCipheriv(algorithm, key, iv); encryptor.write(strBuffer); encryptor.end(); **return** encryptor.read(); } Let’s see how to decrypt the encrypted data. First of all we need to decrypt our ecrypted key using the CMK. Following diagram illustrates that. The code snippet I have posted earlier can be used to do this (just the same as regular data decryption). http://docs.aws.amazon.com The last step is decrypting the data. Following diagram illustrates that. http://docs.aws.amazon.com A sample code to decrypt the data we encrypted above using AES-CBC is shown below. decryptAES(key, buffer) { algorithm = 'AES-256-CBC'; function const **const** iv = **new** Buffer('00000000000000000000000000000000', 'hex'); encryptor = crypto.createDecipheriv(algorithm, key, iv); encryptor.write(buffer); encryptor.end(); **return** encryptor.read(); } Following is a code snippet to encrypt and decrypt a string using envelope encryption. generateDataKey().then(data => { cipherTextBlob = encryptAES(data.Plaintext, Buffer('abc', 'utf-8')); ( i = 0; i < data.Plaintext.length; i++) {data.Plaintext[i] = ;}decrypt(data.CiphertextBlob).then(key => { dataBuffer = decryptAES(key, cipherTextBlob);console.log(dataBuffer.toString('utf-8'));});}); const new for let null const Encryption context Other than all of these AWS KMS provides support for encryption context to further enhance the security. There are some security issues that can be mitigated by using an encryption context. To learn more about encryption context and how to use it, please head over . here OK we are at the end. This has been a pretty lengthy article. But I hope that you have learned something from this. Now its your time to check AWS KMS out!!!