diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go index 1d50fbe06..d9b3c71fc 100644 --- a/weed/s3api/s3api_object_handlers.go +++ b/weed/s3api/s3api_object_handlers.go @@ -780,7 +780,8 @@ func (s3a *S3ApiServer) streamFromVolumeServersWithSSE(w http.ResponseWriter, r s3err.WriteErrorResponse(w, r, s3err.ErrInternalError) return fmt.Errorf("no SSE-S3 metadata") } - keyData := entry.Extended[s3_constants.SeaweedFSSSES3Key] + keyDataB64 := entry.Extended[s3_constants.SeaweedFSSSES3Key] + keyData, _ := base64.StdEncoding.DecodeString(string(keyDataB64)) keyManager := GetSSES3KeyManager() sseS3Key, err := DeserializeSSES3Metadata(keyData, keyManager) if err != nil { @@ -1025,11 +1026,17 @@ func (s3a *S3ApiServer) createSSES3DecryptedReaderFromEntry(r *http.Request, enc return nil, fmt.Errorf("no extended metadata found") } - keyData, exists := entry.Extended[s3_constants.SeaweedFSSSES3Key] + keyDataB64, exists := entry.Extended[s3_constants.SeaweedFSSSES3Key] if !exists { return nil, fmt.Errorf("SSE-S3 metadata not found") } + // Decode from base64 (matches storage format) + keyData, err := base64.StdEncoding.DecodeString(string(keyDataB64)) + if err != nil { + return nil, fmt.Errorf("failed to decode SSE-S3 metadata: %w", err) + } + keyManager := GetSSES3KeyManager() sseS3Key, err := DeserializeSSES3Metadata(keyData, keyManager) if err != nil { diff --git a/weed/s3api/s3api_object_handlers_put.go b/weed/s3api/s3api_object_handlers_put.go index 3df15edf9..d752ea3ae 100644 --- a/weed/s3api/s3api_object_handlers_put.go +++ b/weed/s3api/s3api_object_handlers_put.go @@ -495,14 +495,16 @@ func (s3a *S3ApiServer) putToFiler(r *http.Request, uploadUrl string, dataReader // Set SSE-C metadata if customerKey != nil && len(sseIV) > 0 { - entry.Extended[s3_constants.SeaweedFSSSEIV] = sseIV + // Use helper function to store IV as base64 (matches filer behavior) + StoreSSECIVInMetadata(entry.Extended, sseIV) entry.Extended[s3_constants.AmzServerSideEncryptionCustomerAlgorithm] = []byte("AES256") entry.Extended[s3_constants.AmzServerSideEncryptionCustomerKeyMD5] = []byte(customerKey.KeyMD5) } // Set SSE-KMS metadata if sseKMSKey != nil { - entry.Extended[s3_constants.SeaweedFSSSEKMSKeyHeader] = sseKMSMetadata + // Store metadata as base64 (matches filer behavior and response reading expectation) + entry.Extended[s3_constants.SeaweedFSSSEKMSKeyHeader] = []byte(base64.StdEncoding.EncodeToString(sseKMSMetadata)) // Set standard SSE headers for detection entry.Extended[s3_constants.AmzServerSideEncryption] = []byte("aws:kms") entry.Extended[s3_constants.AmzServerSideEncryptionAwsKmsKeyId] = []byte(sseKMSKey.KeyID) @@ -511,7 +513,8 @@ func (s3a *S3ApiServer) putToFiler(r *http.Request, uploadUrl string, dataReader // Set SSE-S3 metadata if sseS3Key != nil && len(sseS3Metadata) > 0 { - entry.Extended[s3_constants.SeaweedFSSSES3Key] = sseS3Metadata + // Store metadata as base64 (matches filer behavior) + entry.Extended[s3_constants.SeaweedFSSSES3Key] = []byte(base64.StdEncoding.EncodeToString(sseS3Metadata)) // Set standard SSE header for detection entry.Extended[s3_constants.AmzServerSideEncryption] = []byte("AES256") glog.V(3).Infof("putToFiler: storing SSE-S3 metadata for object %s with keyID %s", filePath, sseS3Key.KeyID)