代码之家  ›  专栏  ›  技术社区  ›  Scott Holtzman

通过加密S3存储桶上的预签名url返回的putObject返回的签名不匹配

  •  -1
  • Scott Holtzman  · 技术社区  · 7 年前

    SignatureDoesNotMatch

    兰姆达

        const generatepresignedurl = (req, res, callback) => {
    
        var fileurls = [];
        const body = JSON.parse(req.body);
        const theBucket = body['theBucket'];
        const theKey = body['theKey'];
        const theContentType = body['theContentType'];
        const theOperation = body['theOperation'];
    
        /*setting the presigned url expiry time in seconds, also check if user making the request is an authorized user
         for your app (this will be specific to your app’s auth mechanism so i am skipping it)*/
        const signedUrlExpireSeconds = 60 * 60;
    
        if (theOperation == 'getObject') {
            var params = {
                Bucket: theBucket,
                Key: theKey,
                Expires: signedUrlExpireSeconds
            };
        } else {
            var params = {
                Bucket: theBucket,
                Key: theKey,
                Expires: signedUrlExpireSeconds,
                ACL: 'bucket-owner-full-control',
                ContentType: theContentType,
                ServerSideEncryption: 'AES256'
            };
        }
    
        s3.getSignedUrl(theOperation, params, function (err, url) {
            if (err) {
                console.log('Error Getting Presigned URL from AWS S3');
                // callback(null, ({ success: false, message: 'Pre-Signed URL error', urls: fileurls }));
                callback(null, {error: err});
            }
            else {
                fileurls[0] = url;
                console.log('Presigned URL: ', fileurls[0]);
                callback(null, { success: true, message: 'AWS SDK S3 Pre-signed urls generated successfully.', urls: fileurls });
            }
        });
    
    }
    

    呼叫代码如下:

    生成预签名的Url

    Function callStandAloneAWSService(lambda As String, request As String, contentType As String) As String
    
        Dim httpserver As New MSXML2.XMLHTTP
    
        With httpserver
    
            Dim theURL As String
            theURL = AWS_WEBSERVICE_URL_DEV
    
            .Open "POST", theURL & lambda 'variable that contains generatepresignedurl
    
            .setRequestHeader "Content-type", contentType
    
            .send request
    
            Do: DoEvents: Loop Until .readyState = 4 'make sure we are ready to recieve response
    
            callStandAloneAWSService = .responseText
    
        End With
    
    End Function
    

    (原始问题没有ServerSideEncryption标题)

    Function uploadToPreSignedURL(url As String, whichFile As String, contentType) As Boolean
    
        'code to create binaryFile
    
        Dim httpserver As New MSXML2.XMLHTTP
    
        With httpserver
    
            .Open "POST", url
            .setRequestHeader "Content-type", "text/plain" 'contentType
            .send binaryFile
            Do: DoEvents: Loop Until .readyState = 4 'make sure we are ready to recieve response
    
            If Len(.responseText) = 0 Then
    
                uploadToPreSignedURL = True
    
            Else
    
                'extract error message from xml and write to report mail
    
            End If
    
        End With
    
    End Function
    

    桶政策

    {
        "Version": "2012-10-17",
        "Id": "S3PolicyId1",
        "Statement": [
            {
                "Sid": "DenyIncorrectEncryptionHeader",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:PutObject",
                "Resource": "arn:aws:s3:::mybiggetybucket/*",
                "Condition": {
                    "StringNotEquals": {
                        "s3:x-amz-server-side-encryption": "AES256"
                    }
                }
            },
            {
                "Sid": "DenyUnEncryptedObjectUploads",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:PutObject",
                "Resource": "arn:aws:s3:::mybiggetybucket/*",
                "Condition": {
                    "Null": {
                        "s3:x-amz-server-side-encryption": "true"
                    }
                }
            }
        ]
    }
    

    aws s3api put对象--bucket mybiggetybucket--key test.json--body package-lock.json--服务器端加密“AES256”

    1 回复  |  直到 7 年前
        1
  •  2
  •   jarmod    5 年前

    Server Side Encryption 文件:

    无法对使用上载的对象强制执行SSE-S3加密 预先签名的URL。只能使用指定服务器端加密 AWS管理控制台或HTTP请求头。更多 Specifying Conditions in a Policy .

    我能够得到类似的工作。我需要使用PUT而不是POST,我需要提供 x-amz-server-side-encryption:AES256

    const axios = require('axios');
    const AWS = require('aws-sdk');
    
    const s3 = new AWS.S3();
    
    const params = {
      Bucket: 'mybucket',
      Key: 'myfolder/myfile.txt',
      Expires: 60 * 60,
      ACL: 'bucket-owner-full-control',
      ContentType: 'text/plain',
      ServerSideEncryption: 'AES256',
    };
    
    const axiosConfig = {
      headers: {
        'Content-Type': 'text/plain',
        'x-amz-server-side-encryption': 'AES256',
      },
    };
    
    const uploadTextFile = (presignedurl) => {
      axios.put(presignedurl, 'some text here', axiosConfig).then((res) => {
        console.log('File uploaded');
      }).catch((error) => {
        console.error(error);
      });
    };
    
    s3.getSignedUrl('putObject', params, (err, url) => {
      if (err) {
        console.error(err);
      } else {
        console.log('Pre-signed URL:', url);
        uploadTextFile(url);
      }
    });