0

コンテンツを暗号化し、Azure で証明書を設定して読み戻せるようにすることで、web.config の機密データを保護することに関するMSDN ブログの投稿を読みました。

ただし、Visual Studio Azure Deployment プロジェクトの「サービス構成」.cscfg ファイルには極秘データがあります。接続文字列やその他の機密データをここに保存して、これも Azure 上のテスト システムを同等のテスト バックエンド サービスに転送できるようにします。

このデータは、ブログ投稿で説明されているように、WebConfigurationManager ではなく CloudConfigurationManager (.GetSetting("AwsSecretKey") など) を使用してアクセスされます。

このデータを同様の方法で保護することは可能ですか? テストと本番環境で異なる AWS と SQL の接続文字列を使用し、本番環境のキーが私や他の開発スタッフから隠されていることが重要です。

4

1 に答える 1

4

はい、展開構成でアップロードされた x509 証明書を使用してこれを行います。ただし、設定は、秘密鍵を保護するためのポリシー/手順と同じくらい安全です! ServiceConfiguration の値を復号化するために Azure ロールで使用するコードを次に示します。

/// <summary>Wrapper that will wrap all of our config based settings.</summary>
public static class GetSettings
{
    private static object _locker = new object();

    /// <summary>locked dictionary that caches our settings as we look them up.  Read access is ok but write access should be limited to only within a lock</summary>
    private static Dictionary<string, string> _settingValues = new Dictionary<string, string>();

    /// <summary>look up a given setting, first from the locally cached values, then from the environment settings, then from app settings.  This handles caching those values in a static dictionary.</summary>
    /// <param name="settingsKey"></param>
    /// <returns></returns>
    public static string Lookup(string settingsKey, bool decrypt = false)
    {
        // have we loaded the setting value?
        if (!_settingValues.ContainsKey(settingsKey))
        {
            // lock our locker, no one else can get a lock on this now
            lock (_locker)
            {
                // now that we're alone, check again to see if someone else loaded the setting after we initially checked it
                //  if no one has loaded it yet, still, we know we're the only one thats goin to load it because we have a lock
                //  and they will check again before they load the value
                if (!_settingValues.ContainsKey(settingsKey))
                {
                    var lookedUpValue = "";
                    // lookedUpValue = RoleEnvironment.IsAvailable ? RoleEnvironment.GetConfigurationSettingValue(settingsKey) : ConfigurationManager.AppSettings[settingsKey];
                    // CloudConfigurationManager.GetSetting added in 1.7 - if in Role, get from ServiceConfig else get from web config.
                    lookedUpValue = CloudConfigurationManager.GetSetting(settingsKey);
                    if (decrypt)
                        lookedUpValue = Decrypt(lookedUpValue);
                    _settingValues[settingsKey] = lookedUpValue;
                }
            }

        }

        return _settingValues[settingsKey];
    }

    private static string Decrypt(string setting)
    {
        var thumb = Lookup("DTSettings.CertificateThumbprint");
        X509Store store = null;

        try
        {
            store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

            store.Open(OpenFlags.ReadOnly);
            var cert = store.Certificates.Cast<X509Certificate2>().Single(xc => xc.Thumbprint == thumb);

            var rsaProvider = (RSACryptoServiceProvider)cert.PrivateKey;
            return Encoding.ASCII.GetString(rsaProvider.Decrypt(Convert.FromBase64String(setting), false));
        }
        finally
        {
            if (store != null)
                store.Close();
        }
    }
}

次に、エミュレーターまたはデプロイされた環境でのみ値を復号化するために活用できRoleEnvironment.IsAvailableます。これにより、ローカル デバッグ用の key="MyConnectionString" を使用した暗号化されていないアプリ設定を使用して、ローカル IIS で Web ロールを実行できます (エミュレーターなし)。

ContextConnectionString = GetSettings.Lookup("MyConnectionString", decrypt: RoleEnvironment.IsAvailable);

次に、例を完成させるために、次のコードを使用して単純な WinForsm アプリを作成し、指定された証明書で値を暗号化/復号化しました。当社のプロダクション チームは、プロダクション証明書へのアクセスを維持し、WinForms アプリを使用して必要な値を暗号化します。次に、開発チームに暗号化された値を提供します。ソリューションの完全な作業用コピーは、ここにあります。WinForms アプリのメイン コードは次のとおりです。

    private void btnEncrypt_Click(object sender, EventArgs e)
    {
        var thumb = tbThumbprint.Text.Trim();
        var valueToEncrypt = Encoding.ASCII.GetBytes(tbValue.Text.Trim());

        var store = new X509Store(StoreName.My, rbLocalmachine.Checked ? StoreLocation.LocalMachine : StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);
        var cert = store.Certificates.Cast<X509Certificate2>().Single(xc => xc.Thumbprint == thumb);

        var rsaProvider = (RSACryptoServiceProvider)cert.PublicKey.Key;
        var cypher = rsaProvider.Encrypt(valueToEncrypt, false);
        tbEncryptedValue.Text = Convert.ToBase64String(cypher);
        store.Close();
        btnCopy.Enabled = true;
    }

    private void btnDecrypt_Click(object sender, EventArgs e)
    {
        var thumb = tbThumbprint.Text.Trim();
        var valueToDecrypt = tbEncryptedValue.Text.Trim();

        var store = new X509Store(StoreName.My, rbLocalmachine.Checked ? StoreLocation.LocalMachine : StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);
        var cert = store.Certificates.Cast<X509Certificate2>().Single(xc => xc.Thumbprint == thumb);

        var rsaProvider = (RSACryptoServiceProvider)cert.PrivateKey;
        tbDecryptedValue.Text = Encoding.ASCII.GetString(rsaProvider.Decrypt(Convert.FromBase64String(valueToDecrypt), false));
    }

    private void btnCopy_Click(object sender, EventArgs e)
    {
        Clipboard.SetText(tbEncryptedValue.Text);
    }
于 2013-03-05T02:13:48.690 に答える