Azure 存储 blob 客户端加密不解密 Java

Posted

技术标签:

【中文标题】Azure 存储 blob 客户端加密不解密 Java【英文标题】:Azure storage blob client side encryption does not decrypt Java 【发布时间】:2020-01-10 17:50:00 【问题描述】:

Azure 存储 blob,使用客户端加密、使用 CEK 和 KEK 上传了一个 blob。现在尝试在客户端使用 KEK 下载解密文件。但是文件被下载并且不解密。仅显示加密文件。

public class KeyVaultGettingStarted 

    public static void main(String[] args) throws StorageException,
            NoSuchAlgorithmException, InterruptedException, ExecutionException,
            URISyntaxException, InvalidKeyException, IOException 
        Utility.printSampleStartInfo("KeyVaultGettingStarted");

        // Get the key ID from Utility if it exists.
        String keyID = Utility.keyVaultKeyID;

        // If no key ID was specified, we will create a new secret in Key Vault.
        // To create a new secret, this client needs full permission to Key
        // Vault secrets.
        // Once the secret is created, its ID can be added to App.config. Once
        // this is done,
        // this client only needs read access to secrets.
        if (keyID == null || keyID.isEmpty()) 
            keyID = KeyVaultUtility.createSecret("KVGettingStartedSecret");
        

        // Retrieve storage account information from connection string
        // How to create a storage connection string -
        // https://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/
        CloudStorageAccount storageAccount = CloudStorageAccount
                .parse(Utility.storageConnectionString);

        CloudBlobClient client = storageAccount.createCloudBlobClient();
        CloudBlobContainer container = client
                .getContainerReference("blobencryptioncontainer"
                        + UUID.randomUUID().toString().replace("-", ""));
        container.createIfNotExists();

        // Construct a resolver capable of looking up keys and secrets stored in
        // Key Vault.

        KeyVaultKeyResolver cloudResolver = new KeyVaultKeyResolver(
                KeyVaultUtility.GetKeyVaultClient());


        // To demonstrate how multiple different types of key can be used, we
        // also create a local key and resolver.
        // This key is temporary and won't be persisted.
        final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(1024);
        final KeyPair wrapKey = keyGen.generateKeyPair();

        RsaKey rsaKey = new RsaKey("rsaKey1", wrapKey);
        LocalResolver resolver = new LocalResolver();
        resolver.add(rsaKey);

        // If there are multiple key sources like Azure Key Vault and local KMS,
        // set up an aggregate resolver as follows.
        // This helps users to define a plug-in model for all the different key
        // providers they support.
        AggregateKeyResolver aggregateResolver = new AggregateKeyResolver();
        aggregateResolver.Add(resolver);
        aggregateResolver.Add(cloudResolver);


        // Set up a caching resolver so the secrets can be cached on the client.
        // This is the recommended usage
        // pattern since the throttling targets for Storage and Key Vault
        // services are orders of magnitude
        // different.
        CachingKeyResolver cachingResolver = new CachingKeyResolver(1,
                aggregateResolver);

        // Create a key instance corresponding to the key ID. This will cache
        // the secret.
        IKey cloudKey = cachingResolver.resolveKeyAsync(keyID).get();

        System.out.println(cloudKey.toString());

        try 
            container.createIfNotExists();
            int size = 5 * 1024 * 1024;
            String a = "this is the encrypted message.";

            // The first blob will use the key stored in the Azure Key Vault.
            CloudBlockBlob blob = container.getBlockBlobReference("blockblob1");

            BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(
                    cloudKey, null);

            // Set the encryption policy on the request options.
            BlobRequestOptions uploadOptions = new BlobRequestOptions();
            uploadOptions.setEncryptionPolicy(uploadPolicy);

            System.out.println("Uploading the 1st encrypted blob.");

            // Upload the encrypted contents to the blob.
            ByteArrayInputStream inputStream = new 
            ByteArrayInputStream(a.getBytes());
            blob.upload(inputStream, size, null, uploadOptions, null);

            // Download the encrypted blob.
            BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(
                    null,cachingResolver);

            // Set the decryption policy on the request options.
            BlobRequestOptions downloadOptions = new BlobRequestOptions();
            downloadOptions.setEncryptionPolicy(downloadPolicy);
            System.out.println(downloadOptions.toString());

            System.out.println("Downloading the 1st encrypted blob.");

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

            blob.download(outputStream, null, downloadOptions, null);
            blob.downloadToFile("C:\\Users\\kashyap\\Downloads\\abc.txt");

Azure 存储 blob,使用客户端加密、使用 CEK 和 KEK 上传了一个 blob。现在尝试在客户端使用 KEK 下载解密文件。但是文件被下载并且不解密。仅显示加密文件。

【问题讨论】:

是否使用相同的密钥来解密和加密 blob? 我的解决方案解决了您的问题吗? 【参考方案1】:

这两个文档可能会给你一些帮助:

doc1

doc2

请将下载方式改成:

blob.downloadToFile("C:\\Users\\kashyap\\Downloads\\abc.txt", null, uploadOptions, null);

可以看到我上传到azure blob的图片坏了:

但是当我用这个方法下载的时候,又变回了图片:

它对我有用。如果您还有其他问题,请告诉我。

【讨论】:

@KashyapSoni 很高兴为您提供帮助。 我有同样的问题 - Azure 存储 blob 客户端加密不解密 DOTNET - 我使用了 await blob.DownloadToStreamAsync(ms, null, options, null);

以上是关于Azure 存储 blob 客户端加密不解密 Java的主要内容,如果未能解决你的问题,请参考以下文章

Azure 客户端加密

在 Azure Blob 存储中加密图像

Azure CDN URL使用令牌身份验证和Blob存储SAS重写规则

无法加密 Azure CloudFile。能够加密 Azure Blob

索引 Azure 存储上的加密 Blob

是否可以使用密钥保管库加密文件并使用“Azure 存储数据移动库”将其存储在存储帐户中