1

次のコードでは:symmetricCryptoKeyは、暗号化された対称キーの復号化されたバージョンであるため、常に保護する必要があるプライベート情報を表します。

質問:

  • マルチテナント環境 (Azure でホストされている) でメモリを保護するために追加できる拡張機能はありsymmetricCryptoKeyますか?

TL;DR コード サンプル

                byte[] symmetricCryptoKey = RSA.Decrypt(key.Key, true);

                AesManaged algorithm = new AesManaged();
                algorithm.IV = key.iv;
                algorithm.Key = symmetricCryptoKey;
                keyCache[key.Version] = algorithm;

完全なコードファイル ... Codeplex ソース

using EncryptDecrypt.Exceptions;
using Microsoft.WindowsAzure.Storage;
using System;
using System.Collections.Generic;
using System.Data.Services.Client;
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace EncryptDecrypt
{
    /// <summary>
    /// Store the various encryption keys so that we don't need to load them from storage all the time
    /// </summary>
    /// <remarks>
    /// Is there something we should be doing to secure the memory used by this class?
    /// </remarks>
    internal class AzureTableCryptoKeyStore : IDisposable
    {
        private Dictionary<int, SymmetricAlgorithm> keyCache = new Dictionary<int, SymmetricAlgorithm>();
        internal CloudStorageAccount KeyStoreAccount { get; private set; }

        internal AzureTableCryptoKeyStore(CloudStorageAccount acct)
        {
            this.KeyStoreAccount = acct;

            SymmetricKeyStore keyTable = new SymmetricKeyStore(acct);
            List<SymmetricKey> allKeys = null;

            try
            {
                allKeys = keyTable.GetAllKeys();
            }
            catch (DataServiceQueryException dsq)
            {
                if (dsq.Response.StatusCode == (int)HttpStatusCode.NotFound)
                {
                    //Table hasn't been created, so there aren't any keys. Guess we'll just go with it. 
                    allKeys = new List<SymmetricKey>(0);
                }
                else
                {
                    throw new AzureTableCryptoInitializationException("Failed to load encryption keys from storage", dsq);
                }
            }
            catch (DataServiceClientException dsce)
            {
                if (dsce.StatusCode == (int)HttpStatusCode.NotFound)
                {
                    //Table hasn't been created, so there aren't any keys. Guess we'll just go with it. 
                    allKeys = new List<SymmetricKey>(0);
                }
                else
                {
                    throw new AzureTableCryptoInitializationException("Failed to load encryption keys from storage", dsce);
                }
            }
            catch (Exception ex)
            {
                throw new AzureTableCryptoInitializationException("Could not load encryption keys table", ex);
            }


            foreach (var key in allKeys)
            {
                try
                {
                    X509Certificate2 certificate = CertificateHelper.GetCertificateByThumbprint(key.CertificateThumbprint);
                    if (certificate == null)
                    {
                        //Can't find the cert for this key, just continue
                        continue;
                    }

                    RSACryptoServiceProvider RSA;
                    try
                    {
                        RSA = (RSACryptoServiceProvider)certificate.PrivateKey;
                    }
                    catch (CryptographicException)
                    {
                        throw new AzureTableCryptoPrivateKeyNotAccessibleException(key.Version, key.CertificateThumbprint);
                    }

                    byte[] symmetricCryptoKey = RSA.Decrypt(key.Key, true);

                    AesManaged algorithm = new AesManaged();
                    algorithm.IV = key.iv;
                    algorithm.Key = symmetricCryptoKey;
                    keyCache[key.Version] = algorithm;
                }
                catch (AzureTableCryptoException)
                {
                    //Just rethrow these
                    throw;
                }
                catch (Exception ex)
                {
                    throw new AzureTableCryptoInitializationException("Error initializing crypto key version " + key.Version, ex);
                }
            }
        }

        internal ICryptoTransform GetDecryptor(int version)
        {
            return GetAlgorithm(version).CreateDecryptor();
        }

        internal ICryptoTransform GetEncryptor(int version)
        {
            return GetAlgorithm(version).CreateEncryptor();
        }

        private SymmetricAlgorithm GetAlgorithm(int version)
        {
            SymmetricAlgorithm algo;
            if (!keyCache.TryGetValue(version, out algo))
            {
                throw new AzureTableCryptoNotFoundException(version);
            }
            return algo;
        }

        public void Dispose()
        {
            Dictionary<int, SymmetricAlgorithm> cache = keyCache;
            keyCache = null;

            foreach (var algo in cache.Values)
            {
                algo.Clear();
                algo.Dispose();
            }
        }
    }
}
4

1 に答える 1

2

メモリ スニファーがキーを取得するのを防ぐために使用できる SecureString のようなものがあります。

SecureString はどのように「暗号化」され、引き続き使用できますか?

プログラム自体が解読するためのすべての情報を持っている場合、文字列を表示するために必要なすべての情報がコンピュータにあるため、もちろん完全ではありません。ただし、侵害される可能性のあるシナリオは減少します。

于 2012-11-15T03:11:32.960 に答える