Machina CLI Key Stack and Key Vault diagram | Ionic Machina Developers Blog

Machina CLI Key Stack and Vault

Machina CLI is a handy command-line tool that enables you to quickly create keys, attach key attributes, and encrypt and decrypt data right from your terminal. In fact, anything you can do with Machina SDKs you can do with machina CLI. But how are you storing your keys?  Writing them on a piece of paper or storing them in a digital file? No need for that. The CLI also includes some useful features that let you store keys securely on your local machine. Namely, a key stack and a key vault. This blog will explain how to use the key stack and key vault, and show how you can store keys for offline decryption later.

Working with Machina CLI

This blog post assumes you have a Machina account and run the “Hello, World!” example in our Getting Started guide. If you don’t have an account, simply visit Start for Free on the Machina Developers site. It also assumes you have installed the Machina CLI. If you haven’t installed the CLI yet, go here for instructions.

Assuming that you have enrolled your device, one of the first things to know about the CLI is that you can run multiple commands.  For long lines or clarity, use your shell continuation character. For example here is profile list and profile show in bash:

is-mbp-rick:test rick$ machina \
> 	--devicetype plaintext \
> 	--devicefile ${HOME}/.ionicsecurity/profiles.pt \
> 	profile list profile show

Number of Profiles: 3

Name: AdvocateRick
DeviceId: HCzG.4.4d6a350b-7086-4129-bc0f-81b205edecfb
Server: https://dev-api.ionic.com

Name: SDK_Demo
DeviceId: Ehp0.H.96202c7a-c73e-4fea-5803-34933d42dfd4
Server: https://api.ionic.com

Name: machina
DeviceId: HVxG.4.548361af-5fa4-41af-43a3-f776e63450b5
Server: https://preview-api.ionic.com


Name: AdvocateRick
DeviceId: HCzG.4.4d6a350b-7086-4129-bc0f-81b205edecfb
Server: https://dev-api.ionic.com

If you need assistance in generating CLI commands, try using the command generator tool in Machina Developers. Here we are using the profile list command to list the profiles in a plaintext persistor and the profile show to obtain the active profile in the plaintext persistor. In case you are wondering, a “persistor” is a method for encrypting and storing your device authentication credentials.

Key Stack

Let’s look at the key stack first.  The key stack is an internal stack that stores keys.

Diagram of Ionic Machina CLI Key Stack and Key Vault

Both the key create and key fetch commands have a --push option.  This option pushes a key onto the internal key stack. One use case is to have one key encrypt multiple strings or files.  Let’s look at an example using the default persistor:

is-mbp-rick:tests rick$ machina \
>      key create \
>      --push \
> 	--externids bison \
>      chunk encrypt \
>	--pull /
>	--out bison.en /
>	--instr "Bison are native to the American plains"
{
	"keyCount" : 1,
	"keys" : [
    	{
        	"deviceId" : "BKAl.H.ccfedf1f-e5ba-46a4-50bc-daf5d05d9448",
        	"originId" : "ionic-keyserver",
        	"keyId" : "BKAlHP8zw2k",
        	"keyData" : "yc6exGjoKQ31SEJDZFa6WPwnfDTNdkcpIpWdhn8aecs=",
        	"attrs" : {
            	"ionic-external-id" : [
                	"bison"
            	]
        	},
        	"mattrs" : {
        	},
        	"obligs" : {
        	}
    	}
	]
}

Here a key is created with an externid, “bison”.  (We’ll see why later.)  The key is pushed onto the key stack with the --push option.  The chunk encrypt command uses the key from the key stack with the --pull option and encrypts the string “Bison are native to the American plains” specified by --instr. The encrypted data is stored in file bison.en.

Let’s decrypt the encrypted data with the chunk decrypt command.

is-mbp-rick:tests rick$ machina chunk decrypt --in bison.en
Bison are native to the American plains

There is no need for the key with chunk decryption because the key is included in the encrypted data. Decryption can occur offline, meaning that to decrypt a string, you don’t need to be connected to the Ionic server.

Now let’s look at using that key again.

is-mbp-rick:tests rick$ machina \
>       key fetch \
>       --externids bison /
>       --simple \
>       --push \
>       chunk encrypt \
>       --pull \
>       --out bison1.en \
>       --instr "Today bison can be found in zoos"
{
	"keyCount" : 1,
	"keys" : [
    	{
        	"keyId" : "BKAlHP8zw2k",
        	"keyData" : "yc6exGjoKQ31SEJDZFa6WPwnfDTNdkcpIpWdhn8aecs="
    	}
	]
}

The same key is fetched with the externid “bison” and pushes the key onto the key stack.  Note the --simple option is used to show a reduced output.  The chunk encrypt command pops the key off the stack and uses it to encrypt the string “Today bison can be found in zoos”.  To verify, we’ll decrypt the data.

is-mbp-rick:tests rick$ machina chunk decrypt --in bison1.en
Today bison can be found in zoos

This will also work with the file encrypt command which also has the --pull option.

Below is a diagram of the key stack, and its relationship to the --push and –-pull command options and a preview of the key stack’s relationship with the key vault.

Key Vault

The key vault is an encrypted file that stores keys. To use a key vault, the vault load command is required.  Let’s see what’s in a previously created key vault using the vault list command.

is-mbp-rick:tests rick$ machina vault load --file key_vault.bin vault list

Key vault contains 2 keys:
Key ID: BKAlIf931xs (external ID: physics)
Key ID: BKAlIn951EQ (external ID: chemistry)

The above commands load the existing key vault from the file specified with the --file option, key_vault.bin.  Once the key vault is loaded, it is listed.  If the file specified by the --file option is not present, then it is created.

Now let’s add an existing key to the existing key vault:

 
is-mbp-rick:tests rick$ machina \
>      vault load \
>      --file key_vault.bin \
>      key fetch \
>      --externids bison \
>      --keyout bison.key \
>      --push \
>      vault store \
>      vault list

Key vault contains 3 keys:
Key ID: BKAlHP8zw2k (external ID: bison)
Key ID: BKAlIf931xs (external ID: physics)
Key ID: BKAlIn951EQ (external ID: chemistry)

The first command loads the existing key vault.  Next the key is fetched specifying the externid “bison” and pushes the key onto the key stack.  The key information is written to the file bison.key. (We’ve seen it already a few times).  With the key on the key stack, the vault store command stores it into the loaded key vault.  To confirm the commands worked, the key vault is listed.

So now that we have stored keys into the key vault, let’s fetch them and use them.  For this example, I created a file, sample.txt,which contains the CLI introduction.

is-mbp-rick:tests rick$ more sample.txt
Machina CLI is an app that enables users to manage their profiles and invoke
Machina SDK functions via the command line. Other functions, hashing and
base64 encoding/decoding are also available. The CLI syntax, general options,
and commands are presented below.

Now let’s encrypt that sample file:

is-mbp-rick:tests rick$ machina \
>      vault load \
>      --file key_vault.bin \
>      vault fetch \
>      --externids chemistry \
>      --push \
>      file encrypt 	\
>      --pull \
>      --in sample.txt \
>	--out sample.entxt \
> 	--type auto

As required, the key vault is loaded, but this time a vault fetch command is performed with the externid “chemistry” and the key is pushed onto the key stack.  Next the file encrypt command encrypts the file sample.txt using the key on the key stack with the encrypted output going to file sample.entxt. (Note that the key information is not displayed.  Remember the --keyout option is used to see the key information).

Let’s verify that everything is copacetic by decrypting the file with the file decrypt command and performing a comparison between the original file and the newly decrypted file.  (The key is with the file).

is-mbp-rick:tests rick$ machina \
>      file decrypt \
> 	--out sample.detxt \
> 	--in sample.entxt \
> 	--type auto

is-mbp-rick:tests rick$ diff sample.txt sample.detxt
is-mbp-rick:tests rick$

There are two more vault commands, vault delete and vault clear.  To remove keys from a key vault, use vault delete.  To clear the entire key vault, use the vault clear commands.  Below are examples:

is-mbp-rick:tests rick$ machina \
>      vault load \
>      --file key_vault.bin \
>      vault delete \
>      --externids bison \
>      vault list

Key vault contains 2 keys:
Key ID: BKAlIf931xs (external ID: physics)
Key ID: BKAlIn951EQ (external ID: chemistry)

is-mbp-rick:tests rick$ machina \
>      vault load \
>      --file key_vault.bin \
>      vault clear \
>      vault list

Key vault contains 0 keys:

is-mbp-rick:tests rick$

In Conclusion

The CLI key stack and key vault can be used to retain and reuse keys using the --push and --pull options.  You can store one or multiple keys in a key vault depending on your needs.  Using the externid option, you can select one key out of a collection of keys in the key vault.

To discover more about Machina CLI, go to Machina Developers.  There you’ll find more CLI commands, and a command generator which I used in this blog.  On Machina Developers, there are some tutorials, but my favorite is the CLI keys tutorial written in bash and PowerShell.   And remember, if you need a Machina account, simply visit our Start for Free page to sign up.