热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在节点jsSDK中使用AWSKMS加密-HowtouseAWSKMSEncryptioninthenodejsSDK

IcannotfigureouthowtouploadfilesintoAWSS3usingKMSencryptionfromtheNodeJSSDK.Ikee

I cannot figure out how to upload files into AWS S3 using KMS encryption from the Node JS SDK. I keep getting a 403: Access Denied error. I am able to get files from AWS S3 using KMS.

我无法弄清楚如何使用Node JS SDK中的KMS加密将文件上传到AWS S3。我一直收到403:拒绝访问错误。我可以使用KMS从AWS S3获取文件。

I am reusing most of the code from https://github.com/gilt/node-s3-encryption-client

我正在重用https://github.com/gilt/node-s3-encryption-client中的大部分代码

Main Class
var fs = require('fs'),
    AWS = require('aws-sdk'),
    crypt = require("./crypt"),
    kms,
    s3;

const metadataCipherAlgorithm = 'cipher-algorithm',
      metadataDecryptedEncoding = 'decrypted-encoding'
      metadataKmsKeyName = 'x-amz-key';


/**
 * Constructor - Initializes S3 sdk connection
 */
function S3FileStreamer(key, secret, region) {
    if (region) {
        AWS.config.region = region;
    }
    //set credentials if passed in
    if (key && secret) {
        AWS.config.update({accessKeyId: key, secretAccessKey: secret})
    }
    s3 = new AWS.S3({signatureVersion: "v4"});
    kms = new AWS.KMS({apiVersion: '2014-11-01'});
}

S3FileStreamer.prototype.uploadFile = function(bucket, key, kmsKey, filename, onComplete) {
    var params = {
        Bucket: bucket,
        Key: key,
        Body: fs.readFileSync(filename),
        ContentType: getMimeType(filename)
    };

    params.KmsParams = {
        KeyId: kmsKey,
        KeySpec: 'AES_256'
    }

    kmsUpload(params, function(err, data) {
        if (err) onComplete(err, null);
        else {
            onComplete(err, data);
        }
    });
};

function kmsUpload(params, callback) {
  var kmsParams = params.KmsParams
  if (kmsParams && kmsParams.KeyId) {
    kms.generateDataKey(kmsParams, function(err, kmsData) {
      if (err) {
        callback(err, null);
      } else {
        var helper = new crypt.Helper(kmsData.Plaintext.toString('base64'), {algorithm: params.CipherAlgorithm, decryptedEncoding: params.DecryptedEncoding});
        params.Body = helper.encrypt(params.Body);
        params.Metadata = params.Metadata || {};
        params.Metadata[metadataKmsKeyName] = kmsData.CiphertextBlob.toString('base64');
        if (params.CipherAlgorithm) params.Metadata[metadataCipherAlgorithm] = params.CipherAlgorithm;
        if (params.DecryptedEncoding) params.Metadata[metadataDecryptedEncoding] = params.DecryptedEncoding;
        putObject(params, callback);
      }
    })
  } else {
    putObject(params, callback);
  }
}

function putObject(params, callback) {
  delete params.KmsParams;
  delete params.CipherAlgorithm;
  delete params.DecryptedEncoding;
  s3.putObject(params, callback);
}
Crypt class
var crypto = require('crypto');

/*
  options:
    algorithm: Anything from crypto.getCiphers()
    decryptedEncoding: 'utf8', 'ascii', or 'binary'
    outputEncoding: 'binary', 'base64', or 'hex'
 */
exports.Helper = function(password, options) {
  this.password = password;
  optiOns= options || {};
  this.algorithm = options.algorithm || 'aes-256-cbc';
  this.decryptedEncoding = options.decryptedEncoding || 'utf8';
  this.encryptedEncoding = options.encryptedEncoding || 'base64';
}

exports.Helper.prototype.encrypt = function(unencrypted) {
  var cipher = crypto.createCipher(this.algorithm, this.password);
  return cipher.update(unencrypted, this.decryptedEncoding, this.encryptedEncoding) + cipher.final(this.encryptedEncoding);
}

exports.Helper.prototype.decrypt = function(encrypted) {
  var decipher = crypto.createDecipher(this.algorithm, this.password);
  return decipher.update(encrypted, this.encryptedEncoding, this.decryptedEncoding) + decipher.final(this.decryptedEncoding);
}

Is there something I am missing here, an extra metadata tag that needs to be set?

我在这里缺少什么,需要设置额外的元数据标签吗?

Is the keyId parameter that is passed to the kms generateDataKey method supposed to be in some sort of unique format? I am just simply passing in my key.

传递给kms generateDataKey方法的keyId参数是否应该采用某种独特的格式?我只是简单地传递我的钥匙。

2 个解决方案

#1


1  

While the other answer about checking permissions is undoubtedly correct. I had a hard time finding a good example of how to decode S3 objects using the AES GCM encryption algorithm. I managed to get this code to work based on the aws ruby sdk (as I found the node-s3-encryption-client a little old).

而关于检查权限的另一个答案无疑是正确的。我很难找到一个如何使用AES GCM加密算法解码S3对象的好例子。我设法让这个代码基于aws ruby​​ sdk工作(因为我发现node-s3-encryption-client有点旧)。

/**
 * Decrypt s3 file data
 * @param  {object}   objectData result of s3 get call
 * @param  {Function} callback   function(err, data) returns error or decrypted data
 */
function decrypt(objectData, callback) {
    var metadata = objectData.Metadata || {};
    var kmsKeyBase64 = metadata['x-amz-key-v2'];
    var iv = metadata['x-amz-iv'];
    var tagLen = (metadata['x-amz-tag-len'] || 0)/8;
    var algo = metadata['x-amz-cek-alg'];
    var encryptiOnContext= JSON.parse(metadata['x-amz-matdesc']);

    switch (algo) {
        case 'AES/GCM/NoPadding':
            algo = 'aes-256-gcm';
            break;
        case 'AES/CBC/PKCS5Padding':
            algo = 'aes-256-cbc';
            break;
        default:
            callback(new Error('Unsupported algorithm: ' + algo), null);
            return;
    }

    if (typeof (kmsKeyBase64) === 'undefined') {
        callback(new Error('Missing key in metadata'), null);
        return;
    }

    var kmsKeyBuffer = new Buffer(kmsKeyBase64, 'base64');
    kms.decrypt({
        CiphertextBlob: kmsKeyBuffer,
        EncryptionContext: encryptionContext
    }, function(err, kmsData) {
        if (err) {
            callback(err, null);
        } else {
            var decipher = crypto.createDecipheriv(algo,
                                                   kmsData.Plaintext,
                                                   new Buffer(iv, 'base64'));

            if (tagLen !== 0) {
                // the tag is appended to the data buffer
                var tag = objectData.Body.slice(-tagLen);
                decipher.setAuthTag(tag);
            }
            var data = objectData.Body.slice(0,-tagLen);

            var dec = decipher.update(data, 'binary', 'utf8');
            dec += decipher.final('utf8');

            console.log("Decoded:", dec);
            callback(null, dec);
        }
    });
}

#2


0  

Thanks for all the help. I figured out the solution to my question.

谢谢你的帮助。我想出了我的问题的解决方案。

I went back to using just using the aws-sdk node module and took out all the code I got from the node-s3-encryption-client module.

我回去使用aws-sdk节点模块,并从node-s3-encryption-client模块中取出了所有代码。

All I needed to do in order to successfully upload a file into Amazon S3 using KMS encryption was to add two parameters before passing my params object to the putObject method. These parameters were ServerSideEncryption and SSEKMSKeyId as shown below. It now works!

为了使用KMS加密将文件成功上传到Amazon S3,我需要做的就是在将params对象传递给putObject方法之前添加两个参数。这些参数是ServerSideEncryption和SSEKMSKeyId,如下所示。它现在有效!

var params = {
    Bucket: bucket,
    Key: key,
    Body: fs.readFileSync(filename),
    ContentType: getMimeType(filename),
    ServerSideEncryption: 'aws:kms',
    SSEKMSKeyId: kmsKey
};

s3.putObject(params, function(err, data) {
    if (err) {
      console.log(err);
    } else {
      console.log(data);
});

推荐阅读
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 最详尽的4K技术科普
    什么是4K?4K是一个分辨率的范畴,即40962160的像素分辨率,一般用于专业设备居多,目前家庭用的设备,如 ... [详细]
  • 大家好,我是李白。本文将分享一个从零开始的全栈项目,涵盖了设计、前端、后端和服务端的全面学习过程。通过这个项目,我希望能够帮助初学者更好地理解和掌握全栈开发的技术栈。 ... [详细]
  • 命令模式是一种行为设计模式,它将请求封装成一个独立的对象,从而允许你参数化不同的请求、队列请求或者记录请求日志。本文将详细介绍命令模式的基本概念、组件及其在实际场景中的应用。 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • AppFog 是一个基于 CloudFoundry 的多语言 PaaS(平台即服务)提供商,允许用户在其平台上轻松构建和部署 Web 应用程序。本文将通过详细的图文步骤,指导读者如何在 AppFog 免费云平台上成功部署 WordPress,帮助用户快速搭建个人博客或网站。 ... [详细]
  • 基于Node.js的高性能实时消息推送系统通过集成Socket.IO和Express框架,实现了高效的高并发消息转发功能。该系统能够支持大量用户同时在线,并确保消息的实时性和可靠性,适用于需要即时通信的应用场景。 ... [详细]
  • 【前端开发】深入探讨 RequireJS 与性能优化策略
    随着前端技术的迅速发展,RequireJS虽然不再像以往那样吸引关注,但其在模块化加载方面的优势仍然值得深入探讨。本文将详细介绍RequireJS的基本概念及其作为模块加载工具的核心功能,并重点分析其性能优化策略,帮助开发者更好地理解和应用这一工具,提升前端项目的加载速度和整体性能。 ... [详细]
  • Webpack 初探:Import 和 Require 的使用
    本文介绍了 Webpack 中 Import 和 Require 的基本概念和使用方法,帮助读者更好地理解和应用模块化开发。 ... [详细]
  • javax.mail.search.BodyTerm.matchPart()方法的使用及代码示例 ... [详细]
  • 用阿里云的免费 SSL 证书让网站从 HTTP 换成 HTTPS
    HTTP协议是不加密传输数据的,也就是用户跟你的网站之间传递数据有可能在途中被截获,破解传递的真实内容,所以使用不加密的HTTP的网站是不 ... [详细]
  • 本文介绍了如何利用HTTP隧道技术在受限网络环境中绕过IDS和防火墙等安全设备,实现RDP端口的暴力破解攻击。文章详细描述了部署过程、攻击实施及流量分析,旨在提升网络安全意识。 ... [详细]
  • MySQL 错误:检测到死锁,在尝试获取锁时;建议重启事务(Node.js 环境)
    在 Node.js 环境中,MySQL 数据库操作时遇到了“检测到死锁,在尝试获取锁时;建议重启事务”的错误。本文将探讨该错误的原因,并提供有效的解决策略,包括事务管理优化和锁机制的理解。 ... [详细]
author-avatar
廖蓉以
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有