HMAC in the Cloud

A MAC (Message Authentication Code) is used to sign a message with a shared key. This differs from public key signing which uses a private…

Photo by Volodymyr Hryshchenko on Unsplash

HMAC in the Cloud

A MAC (Message Authentication Code) is used to sign a message with a shared key. This differs from public key signing which uses a private key to sign and a public key to verify. In the following figure, Bob has a message and creates an HMAC-SHA-256 message authentication code using a shared secret symmetric key. When Alice receives the message, she also generates an HMAC-SHA-256 message authentication code using the same key. If it is the same one that Bob sent, she knows that the message has not been changed and that Bob sent it:

KMS (Key Management Store)

In the AWS cloud, we use the KMS (Key Management Store) to create our keys (Figure 1), and which can then be used to encrypt/decrypt data, sign/verify signatures, export data keys, and generate/verify MACs (Message Authentication Codes).

Figure 1: AWS KMS [here]

Overall you have keys that are AWS managed (such as for the Lambda service), Customer managed keys (these are created and managed by the customer), and Custom key stores (these are key stores where the customer has complete control over the keys).

Creating HMAC keys

First, we create our HMAC key with:

We can see we either have HMAC_244, HMAC_256, HMAC_384 and HMAC 512.

Next, we can define the administrative permissions for the key:

And the usage:

The policy becomes:

{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::960372818084:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::2222222:role/aws-service-role/cloud9.amazonaws.com/AWSServiceRoleForAWSCloud9",
"arn:aws:iam::2222222:role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents",
"arn:aws:iam::2222222:role/aws-service-role/elasticache.amazonaws.com/AWSServiceRoleForElastiCache",
"arn:aws:iam::2222222:role/aws-service-role/mrk.kms.amazonaws.com/AWSServiceRoleForKeyManagementServiceMultiRegionKeys",
"arn:aws:iam::2222222:role/aws-service-role/organizations.amazonaws.com/AWSServiceRoleForOrganizations",
"arn:aws:iam::2222222:role/aws-service-role/support.amazonaws.com/AWSServiceRoleForSupport",
"arn:aws:iam::2222222:role/aws-service-role/trustedadvisor.amazonaws.com/AWSServiceRoleForTrustedAdvisor",
"arn:aws:iam::2222222:role/EMR_AutoScaling_DefaultRole",
"arn:aws:iam::2222222:role/EMR_DefaultRole",
"arn:aws:iam::2222222:role/EMR_EC2_DefaultRole"
]
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::2222222:role/aws-service-role/cloud9.amazonaws.com/AWSServiceRoleForAWSCloud9",
"arn:aws:iam::2222222:role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents",
"arn:aws:iam::2222222:role/aws-service-role/elasticache.amazonaws.com/AWSServiceRoleForElastiCache",
"arn:aws:iam::2222222:role/aws-service-role/mrk.kms.amazonaws.com/AWSServiceRoleForKeyManagementServiceMultiRegionKeys",
"arn:aws:iam::2222222:role/aws-service-role/organizations.amazonaws.com/AWSServiceRoleForOrganizations",
"arn:aws:iam::2222222:role/aws-service-role/support.amazonaws.com/AWSServiceRoleForSupport",
"arn:aws:iam::2222222:role/aws-service-role/trustedadvisor.amazonaws.com/AWSServiceRoleForTrustedAdvisor",
"arn:aws:iam::2222222:role/EMR_AutoScaling_DefaultRole",
"arn:aws:iam::2222222:role/EMR_DefaultRole",
"arn:aws:iam::2222222:role/EMR_EC2_DefaultRole"
]
},
"Action": [
"kms:DescribeKey",
"kms:VerifyMac",
"kms:GenerateMac"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::2222222:role/aws-service-role/cloud9.amazonaws.com/AWSServiceRoleForAWSCloud9",
"arn:aws:iam::2222222:role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents",
"arn:aws:iam::2222222:role/aws-service-role/elasticache.amazonaws.com/AWSServiceRoleForElastiCache",
"arn:aws:iam::2222222:role/aws-service-role/mrk.kms.amazonaws.com/AWSServiceRoleForKeyManagementServiceMultiRegionKeys",
"arn:aws:iam::2222222:role/aws-service-role/organizations.amazonaws.com/AWSServiceRoleForOrganizations",
"arn:aws:iam::2222222:role/aws-service-role/support.amazonaws.com/AWSServiceRoleForSupport",
"arn:aws:iam::2222222:role/aws-service-role/trustedadvisor.amazonaws.com/AWSServiceRoleForTrustedAdvisor",
"arn:aws:iam::2222222:role/EMR_AutoScaling_DefaultRole",
"arn:aws:iam::2222222:role/EMR_DefaultRole",
"arn:aws:iam::2222222:role/EMR_EC2_DefaultRole"
]
},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}

This produces a key of:

Generating and verifying a MAC

We can then use “aws kms generate-mac” to produce a MAC:

% aws kms generate-mac --key-id alias/MyHMACKey --message fileb://1.txt \
--mac-algorithm HMAC_SHA_256 --query Mac > 4.out
% cat 4.out
"0FcRVnkMAMYc4MPfkYcNjxEoUSzIMyGf7z5tAPAMk2c="

If we want to verify it, we need to convert it to a binary form (4.mac):

(base) billbuchanan@ASecuritySite .aws % base64 -i 4.out -d > 4.mac
(base) billbuchanan@ASecuritySite .aws % cat 4.mac
ÐWVy
(Q,È3!Ÿï>mð
“g

Finally, we can verify the MAC code with:

% aws kms verify-mac --key-id alias/MyHMACKey --message fileb://1.txt \
--mac-algorithm HMAC_SHA_256 --mac fileb://4.mac

https://billatnapier.medium.com/membership