Расшифровать и скопировать большой двоичный объект в другую учетную запись хранения больших двоичных объектов?

Я использую этот подход для шифрования файлов и хранения их в блочных BLOB-объектах Azure. Я хотел бы скопировать зашифрованный большой двоичный объект в другую учетную запись хранения больших двоичных объектов и расшифровать его в процессе. Я знаю, что можно выполнить операцию «копирования большого двоичного объекта», которая выполняется полностью внутри Azure асинхронно и не загружает содержимое большого двоичного объекта через мой локальный компьютер в пути. Я считаю, что это достигается с помощью метода CloudBlockBlob.StartCopy. Но можно ли сделать это с зашифрованным файлом и расшифровать его при передаче в другую учетную запись хранения?

После указанной выше ссылки мой код выглядит следующим образом. blob.OpenRead работает, но blob2.StartCopy не работает.

BlobEncryptionPolicy policy = new BlobEncryptionPolicy(null, cloudResolver);
BlobRequestOptions options = new BlobRequestOptions() { EncryptionPolicy = policy };
CloudBlockBlob blob = container.GetBlockBlobReference("MyFile.txt");
//var blobStream = blob.OpenRead(null, options); //this works

CloudBlockBlob blob2 = container2.GetBlockBlobReference("MyFile2.txt");
blob2.StartCopy(blob, null, null, options, null); //this fails with: The remote server returned an error: (404) Not Found.

person GregGalloway    schedule 16.02.2016    source источник
comment
Какой пакет и версию nuget вы используете для управления учетной записью хранения?   -  person juvchan    schedule 17.02.2016
comment
@juvchan 6.1 Microsoft.WindowsAzure.Storage DLL   -  person GregGalloway    schedule 17.02.2016
comment
на всякий случай, ваша учетная запись хранения создана в режиме класса или в режиме диспетчера ресурсов? Похоже, что это было раньше для используемого вами nuget.   -  person juvchan    schedule 17.02.2016
comment
@juvchan Classic. Имеет ли это значение?   -  person GregGalloway    schedule 17.02.2016
comment
Я бы сказал: да, всегда лучше быть очень конкретным, чтобы помочь воспроизвести и устранить проблему. Если у меня есть это сомнение, некоторые другие тоже могли бы.   -  person juvchan    schedule 17.02.2016
comment
@juvchan - я не думаю, что имеет значение, если учетная запись хранения будет создана классическим / ARM способом в этом конкретном сценарии. Это влияет на то, как управляются сами учетные записи хранения (с точки зрения Service Management / ARM API). Управление данными внутри учетной записи хранения остается прежним. В обоих случаях он будет использовать имя / ключ учетной записи для управления данными.   -  person Gaurav Mantri    schedule 17.02.2016
comment
Грег - Вы копируете между учетными записями хранения? Поскольку вы использовали переменную container как для исходного, так и для целевого двоичного объекта, я запутался. Также сообщите нам ACL исходного контейнера. Это Private?   -  person Gaurav Mantri    schedule 17.02.2016
comment
@GauravMantri да из учетной записи хранения A в B. Извините. Исправлю мой очищенный образец кода. Оба контейнера частные.   -  person GregGalloway    schedule 17.02.2016
comment
@GauravMantri Большое спасибо за информацию   -  person juvchan    schedule 17.02.2016
comment
Нет, Classic / RM не имеет значения.   -  person Peter Marino - MSFT    schedule 17.02.2016


Ответы (1)


Ответ заключается в том, что шифрование выполняется в клиентской библиотеке хранилища, поэтому, если вы скопируете большой двоичный объект в новую учетную запись хранилища, он все равно будет зашифрован.

Причина сбоя кода в том, что исходный большой двоичный объект находится в Private контейнере. Чтобы копирование между аккаунтами работало, исходный большой двоичный объект должен быть общедоступным. В той же учетной записи хранения вы можете скопировать большой двоичный объект из частного контейнера. AFAIK, ошибка не имеет ничего общего с шифрованием.

Что вы можете сделать, так это создать URL-адрес SAS в исходном большом двоичном объекте, а затем использовать следующее переопределение _ 2_ метод:

public string StartCopy(
    Uri source,
    AccessCondition sourceAccessCondition = null,
    AccessCondition destAccessCondition = null,
    BlobRequestOptions options = null,
    OperationContext operationContext = null
)

Вот пример кода для этого:

    private static void StartCopyAcrossAccount()
    {
        var sourceAccount = new CloudStorageAccount(new StorageCredentials("source-account-name", "source-account-key"), true);
        var sourceContainer = sourceAccount.CreateCloudBlobClient().GetContainerReference("source-container");
        var sourceBlob = sourceContainer.GetBlockBlobReference("blob-name");
        var sourceBlobSas = sourceBlob.GetSharedAccessSignature(new Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy()
            {
                SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1),
                Permissions = Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Read
            });
        var sourceBlobSasUrl = sourceBlob.Uri.AbsoluteUri + sourceBlobSas;

        var targetAccount = new CloudStorageAccount(new StorageCredentials("target-account-name", "target-account-key"), true);
        var targetContainer = targetAccount.CreateCloudBlobClient().GetContainerReference("target-container");
        var targetBlob = targetContainer.GetBlockBlobReference("blob-name");

        var copyId = targetBlob.StartCopy(new Uri(sourceBlobSasUrl), null, null);
    }
person Gaurav Mantri    schedule 17.02.2016
comment
Гаурав, это фантастический ответ, и я многому научился из него о копировании blob. Спасибо! Я отредактировал ответ, чтобы уточнить, что зашифрованный файл остается зашифрованным. С вашим кодом CopyBlob работает успешно, но файл зашифрован в целевом контейнере. Я считаю, что это потому, что copy blob просто дублирует большой двоичный объект, не расшифровывая его при передаче. Не стесняйтесь пересмотреть мою правку к вашему ответу, но я приму ее сейчас. - person GregGalloway; 17.02.2016
comment
I believe that's because copy blob just dups the blob without decrypting it in transit. - Верно. Операция копирования большого двоичного объекта просто копирует байты из источника в цель. Обратите внимание, что операция копирования больших двоичных объектов может использоваться не только для копирования больших двоичных объектов Azure в одну и ту же учетную запись хранения или в разных учетных записях, но также может использоваться для копирования любого общедоступного файла (например, файла, размещенного в Amazon S3) в хранилище больших двоичных объектов. Таким образом, он не знает (не заботится) о блобе. - person Gaurav Mantri; 17.02.2016
comment
Ух ты! Я этого не знал. Думал, это только для копирования blob-to-blob. Если вы не писали в блоге о копировании с S3 без прохождения файла через ваш клиентский компьютер .NET, это было бы хорошим постом. - person GregGalloway; 17.02.2016
comment
Просто примечание: копируя большой двоичный объект, вы можете одновременно заменить метаданные. Если исходный большой двоичный объект зашифрован, не делайте этого, потому что некоторая информация о шифровании хранится в метаданных большого двоичного объекта. Вы можете получить метаданные и добавить к ним или изменить определенные значения, но будьте осторожны, чтобы не заменить их все. Если вы потеряете информацию о шифровании, вы никогда не сможете расшифровать этот большой двоичный объект. - person Robin Shahan - MSFT; 17.03.2016