#aws-kms #secret #encrypting #decrypting #python #nodejs #data

aws_kms_crypt

用于AWS生态系统中加密和解密机密的库

1 个不稳定版本

使用旧的Rust 2015

0.1.0 2018年3月3日

#1732 in 密码学

MIT许可

13KB
164

aws-kms-crypt

用于AWS生态系统中加密和解密机密的库。

特性

  • 互操作性 - Bash、NodeJS、Python和Rust的互操作性实现。
  • 安全性 - 使用KMS生成数据密钥的AES加密(详情)。
  • 简单 - 加密和解密所有支持语言的敏感数据的简单API。

安装

Shell

curl -LO https://raw.githubusercontent.com/sjakthol/aws-kms-crypt/master/shell/aws-kms-crypt.sh && chmod +x aws-kms-crypt.sh

NodeJS

npm install aws-kms-crypt

Python

pip install aws-kms-crypt

Rust

cargo.toml

[dependencies]
aws_kms_crypt = "0.1.0"

用法

一般先决条件

所有实现都需要访问AWS凭证。

加密数据时,凭证必须允许以下操作

  • kms:GenerateDataKey
  • kms:GenerateRandom

解密数据时,凭证必须允许以下操作

  • kms:Decrypt

在这两种情况下,可以通过IAM策略条件进一步限制访问(有关详细信息,请参阅此处)。

Shell脚本(Bash)

位于 shell/aws-kms-crypt.sh 的shell脚本为shell脚本提供加密和解密数据的接口。该脚本需要以下命令/工具才能正常工作

  • aws
  • base64
  • cut
  • jq
  • od
  • openssl
  • sed

加密数据

# No encryption context
echo -n "secretp4ssw0rd!" | ./aws-kms-crypt.sh encrypt --kms-key-id alias/common > encrypted-plan.json

# With encryption context
echo -n "secretp4ssw0rd!" | ./aws-kms-crypt.sh encrypt --kms-key-id alias/common --encryption-context type=plan,entity=admins > encrypted-plan.json

解密数据

$ cat encrypted-plan.json | ./aws-kms-crypt.sh decrypt
secretp4ssw0rd!

Node

nodejs 目录包含一个Node包,实现了基于KMS的加密和解密功能。

需要较新版本的Node(>= 4)。

加密数据

使用模块的 encrypt() 函数加密任何字符串化数据

const kmscrypt = require('aws-kms-crypt')
kmscrypt.encrypt('secretp4ssw0rd!', {
  key: 'alias/common', // Change your key here
  region: 'eu-west-1', // AWS SDK needs to know this
  encryptionContext: { purpose: 'automation' } // optional, can be left out
}, function (err, result) {
  if (err) {
    return console.log('Encryption failed:', err)
  }

  console.log(JSON.stringify(result, null, 2))
  // Console output:
  // {
  //   "EncryptedData": "DPQ0OZ8auGY6ohQb/pypAHJTAPaQre7RrEtziIhRgB8=",
  //   "EncryptedDataKey": "<snip>CBZogG5a",
  //   "EncryptionContext": {
  //     "purpose": "automation"
  //   },
  //   "Iv": "6f93b293f7f77ddf7525bf43038f01c4"
  // }
})

解密数据

要解密之前加密的数据,将解析的JSON文档输入到模块的 decrypt() 函数

const kmscrypt = require('aws-kms-crypt')
kmscrypt.decrypt({
  'EncryptedData': 'TSHgAb4MYkacM9qtdO5OeLQax6jze3P7+zIeUDpakC4=',
  'EncryptedDataKey': '<snip>KqnVhLZY+8',
  'EncryptionContext': {
    'purpose': 'automation'
  },
  'Iv': '6cfbac80d90df12a6357a8f91b57f907'
}, { region: 'eu-west-1' }, function (err, result) {
  if (err) {
    return console.log('Encryption failed:', err)
  }

  console.log(result)
  // => secretp4ssw0rd!
})

Python

python 目录包含一个Python包,实现了基于KMS的加密和解密功能。模块已测试可与Python 2.7和Python 3.5一起使用。

加密数据

import kmscrypt

res = kmscrypt.encrypt('secretp4ssw0rd!', key_id='alias/common', encryption_context={
  'purpose': 'automation'
})

# res is now a dict of form
# {
#   'EncryptedData': 'Su00srm/ru5kd9DLDvi0EdEjjBGUrRBJ06vUmL8QHUU=',
#   'EncryptedDataKey': 'AQIDAHhyrbU/fP<snip>',
#   'EncryptionContext': {'purpose': 'automation'},
#   'Iv': 'd07acff1e2301c468cd3164b8858e477'
# }

解密数据

secret = kmscrypt.decrypt(res)
print(secret) # => secretp4ssw0rd!

Rust

rust 目录包含一个Rust crate,实现了基于KMS的加密和解密功能。

加密数据

extern crate aws_kms_crypt;
extern crate serde_json;

use std::collections::HashMap;

fn main() {
    let mut encryption_context = HashMap::new();
    encryption_context.insert("entity".to_owned(), "admin".to_owned());

    let options = aws_kms_crypt::EncryptOptions {
        encryption_context: encryption_context,
        key: "alias/common".into(),
        region: "eu-west-1".into()
    };

    let data = "secret".into();
    let res = aws_kms_crypt::encrypt(&data, &options);
    println!("{}", serde_json::to_string(&res.unwrap()).unwrap());
}

解密数据

以下是一个使用 serde_json 将JSON编码的秘密反序列化为结构体的完整示例

extern crate aws_kms_crypt;
extern crate serde_json;

fn main() {
    let raw = r#"{
        "EncryptedData": "vRhu+D5LrwNctyhxDvUoqL51YH2LclgUKtDz/2Nxy6Y=",
        "EncryptedDataKey": "<snip>KBFRpvDvpXNXu3e/tTO6Jfi",
        "EncryptionContext": {
            "entity": "admin"
        },
        "Iv": "31bf06a8e0d15a26f1325da6f4f33a9c"
    }"#;

    let data: aws_kms_crypt::EncryptedSecret = serde_json::from_str(raw).unwrap();
    let options = aws_kms_crypt::DecryptOptions {
        region: "eu-west-1".to_owned()
    };

    let res = aws_kms_crypt::decrypt(&data, &options);
    println!("Secret is: {:?}", res.unwrap());
}

它是如何工作的?

加密数据

以下步骤在数据加密时采取

  1. 使用 GenerateRandom KMS API调用(shell)或通过平台特定的随机数API(Node、Python)生成一个随机的16字节初始化向量
  2. 使用 GenerateDataKey KMS API调用生成AES-128算法的数据加密密钥
  3. 使用生成的数据密钥的明文版本和生成的IV进行加密,使用AES-128-CBC算法在本地加密输入数据
  4. 加密的数据、加密数据密钥和初始化向量以以下格式的JSON文档输出
    {
      "EncryptedData": "<base64>",
      "EncryptedDataKey": "<base64>",
      "EncryptionContext": {
        "KeyName1": "1",
        "KeyName2": "2"
      },
      "Iv": "<hex>"
    }
    

此JSON输出可以保存到文件并存储在(半)公开位置,因为它没有透露关于加密数据的任何信息。

解密数据

解密阶段从加密阶段产生的JSON文档中提取数据,并采取以下步骤来解密数据

  1. 使用 Decrypt KMS API调用解密加密数据密钥以检索明文数据加密密钥
  2. 使用明文数据密钥和IV在本地解密加密数据。

未来工作

  • 支持AES-128-CBC以外的其他算法
  • 自动化互操作性测试

依赖项

~20–32MB
~516K SLoC