Implementazione sicura della condivisione dei segreti di crittografia (nome utente, password) nel cloud

7

Sto creando un ambiente multi-tenant (cloud) che deve inviare (o rendere disponibile per il download) i file di configurazione per gli agenti (servizi in background) che ricevono queste informazioni. Una delle informazioni nella configurazione è un nome utente e una password.

Supponendo che l'agente possa essere identificato in sicurezza nel cloud, quale sistema di crittografia e sicurezza utilizzeresti per crittografare, condividere, distribuire queste informazioni sensibili?

È sufficiente una coppia di chiavi Public Private? Sto pensando che i segreti saranno crittografati sulla chiave pubblica di ciascun agente, e il valore non criptato verrà scartato.

Che cosa pensi di questa implementazione? Utilizzerò principalmente C # in questa applicazione, Windows Azure, ASP.NET MVC e Silverlight.

Codice lato agente di esempio (RSACryptoProvider)

Questo genererà la coppia di chiavi pubblica privata in C # e non salverà la chiave sul disco

public static void AssignNewKey(){
    const int PROVIDER_RSA_FULL = 1;
    const string CONTAINER_NAME = "KeyContainer";
    CspParameters cspParams;
    cspParams = new CspParameters(PROVIDER_RSA_FULL);
    cspParams.KeyContainerName = CONTAINER_NAME;
// CspProviderFlags.UseNonExportableKey -- Prevent less-knowledgeable attacks against PK
// CspProviderFlags.UseUserProtectedKey -- Interactively prompt for password
    cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
    cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";
    rsa = new RSACryptoServiceProvider(cspParams);

    rsa.PersistKeyInCsp = false;

    string publicPrivateKeyXML = rsa.ToXmlString(true);
    string publicOnlyKeyXML = rsa.ToXmlString(false);
    // do stuff with keys...
}

Esempio di codice lato agente Opzione 2 (Castello gonfiabile)

public void GenerateKey(string username, string password, string keyStoreUrl)
        {
            IAsymmetricCipherKeyPairGenerator kpg = new RsaKeyPairGenerator();
            kpg.Init(new RsaKeyGenerationParameters(BigInteger.ValueOf(0x13), new SecureRandom(), 1024, 8));
            AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();

            FileStream out1 = new FileInfo(string.Format("{0}secret.asc", keyStoreUrl)).OpenWrite();
            FileStream out2 = new FileInfo(string.Format("{0}pub.asc", keyStoreUrl)).OpenWrite();

            ExportKeyPair(out1, out2, kp.Public, kp.Private, username, password.ToCharArray(), true);

            out1.Close();
            out2.Close();

        }

private static void ExportKeyPair(
            Stream secretOut,
            Stream publicOut,
            AsymmetricKeyParameter publicKey,
            AsymmetricKeyParameter privateKey,
            string identity,
            char[] passPhrase,
            bool armor)
        {
            if (armor)
            {
                secretOut = new ArmoredOutputStream(secretOut);
            }

            PgpSecretKey secretKey = new PgpSecretKey(
                PgpSignature.DefaultCertification,
                PublicKeyAlgorithmTag.RsaGeneral,
                publicKey,
                privateKey,
                DateTime.Now,
                identity,
                SymmetricKeyAlgorithmTag.Cast5,
                passPhrase,
                null,
                null,
                new SecureRandom()
                //                ,"BC"
                );

            secretKey.Encode(secretOut);

            secretOut.Close();

            if (armor)
            {
                publicOut = new ArmoredOutputStream(publicOut);
            }

            PgpPublicKey key = secretKey.PublicKey;

            key.Encode(publicOut);

            publicOut.Close();
        }
    
posta random65537 19.01.2011 - 21:14
fonte

3 risposte

9

La crittografia dei dati con la chiave pubblica di ciascun agente è un modo per autenticare implicitamente l'agente. Non si sa veramente (in una configurazione in cui le comunicazioni attraversano un cloud potenzialmente dannoso) se l'agente ha effettivamente ricevuto i dati, ma si sa che solo l'agente appropriato può decrittografarli; quindi, se i dati sono andati da qualche parte, allora è andato all'agente giusto. Questo sembra il buon strumento per il tuo problema.

Si noti che la crittografia a chiave pubblica potrebbe essere eccessiva. Se è possibile organizzare l'agente ricevente e il mittente dei dati per condividere una chiave segreta comune (solo poche decine di byte casuali), è possibile utilizzare la crittografia simmetrica per crittografare i dati.

Ci sono alcuni trucchi:

  • Se si utilizza uno schema di crittografia a chiave pubblica, il mittente deve conoscere preventivamente le chiavi pubbliche degli agenti e in modo affidabile. A seconda di come crei e distribuisci gli agenti, questo potrebbe essere semplice o meno.

  • La potenza di un agente di ricevere i dati deriva dalla sua conoscenza della sua chiave privata (o della chiave segreta condivisa comune nel caso di crittografia simmetrica). Devi occuparti della memorizzazione di tale chiave privata, perché l'acquisizione di una copia della chiave consentirebbe a un utente malintenzionato di decrittografare i dati crittografati.

  • La crittografia asimmetrica funziona solo per i messaggi limitati. Ad esempio, con RSA a 1024 bit e il solito padding PKCS # 1, c'è un limite rigido a 117 byte in un messaggio. Inoltre, la crittografia e la decodifica RSA non sono troppo veloci (anche se abbastanza veloci per la maggior parte degli scopi). Quindi, è consuetudine utilizzare uno schema ibrido, in cui non si cripta il messaggio stesso, ma una chiave segreta casuale (un mucchio di byte casuali) che si usa quindi per crittografare i dati stessi, con un sistema di crittografia simmetrica (AES ), che è veloce e illimitato nella lunghezza del messaggio.

  • Quando ci sono attaccanti passivi malevoli, spesso ci sono anche attaccanti attivi. Gli attaccanti passivi si limitano a spiare i dati; anche gli attaccanti attivi possono modificarlo. Esistono molti attacchi intelligenti che possono essere apportati modificando subdolamente i dati crittografati e osservando i risultati (le password inviate in una connessione SSL sono state ripristinate in questo modo). Quindi non hai bisogno solo della crittografia, hai anche bisogno di controlli di integrità. Una possibilità è che il mittente firmi i pacchetti crittografati e gli agenti ne verificano la firma prima di provare a decrittografarli.

Una miriade di sistemi schierati si sono imbattuti in questi e non possono essere testati in modo efficiente in anticipo. dovresti usare un formato standard esistente per tutto questo, con una libreria di supporto che ha già attraversato lo sforzo di implementarla correttamente. Ti suggerisco di utilizzare CMS o OpenPGP . Non so se C # supporta già quelli (ne dubito, specialmente nel caso di OpenPGP), ma Bouncy Castle è un open source libreria che fa (ha una versione C #).

Come nota finale, se hai molti agenti che dovrebbero ricevere gli stessi dati, potrebbe essere più efficiente in termini di rete per crittografare i dati una volta con una chiave segreta, che poi cripterai con il chiave pubblica di ciascun agente. Questa è chiamata crittografia broadcast e questo è ciò che fanno i venditori di pay TV (inviano lo stesso contenuto voluminoso a milioni di clienti, che rende la trasmissione non solo utile, ma anche assolutamente necessaria).

    
risposta data 19.01.2011 - 23:13
fonte
2

Coppia chiave pubblica / chiave privata - sembra prestarsi bene a questo scenario, come si deve presumere che i dati nel cloud siano accessibili agli attori malintenzionati. I dati che immessi nel cloud per gli agenti possono essere crittografati e autenticati, nonostante la scarsa sicurezza intorno agli ambienti cloud.

La risposta di Thomas Pornin copre quel lato in modo migliore della mia risposta, quindi aggiungo che è essenziale per ottenere l'implementazione testata , come configurazione debole o scarsa il codice nell'implementazione potrebbe rompere il modello di sicurezza.

    
risposta data 19.01.2011 - 21:38
fonte
0

Come ho capito dalla tua domanda, devi utilizzare il protocollo di autenticazione della rete del computer (" che consente ai nodi di comunicare su una rete non sicura per provare la propria identità l'un l'altro in modo sicuro ") per il tuo lavoro, scopo e specifiche dei protocolli di comunicazione è quello di mantenere:

  • Freschezza:
  • Segreto segreto
  • Resilienza della chiave nota
  • Autenticazione chiave
  • Conferma chiave
  • Autenticazione chiave esplicita

Per ottenere le specifiche di cui sopra è possibile progettare il proprio protocollo di comunicazione, il più semplice da usare:

S è una terza parte affidabile, A & B è il cliente desidera avere una comunicazione sicura.

  • A→S: IDA ║IDB
  • S→A: Kab
  • A→B: Kab║IDA

Possiamo migliorare il protocollo in questo modo:

  • A→S: IDA ║IDB
  • S→A: E(Kas, [Kab])║ E(Kbs, [Kab])
  • A→B: E(Kbs, [Kab]) ║IDA

Ma entrambi i protocolli sopra hanno molti problemi, se vuoi essere sicuro che il protocollo sia abbastanza strong, è meglio usare uno dei protocolli elencati:

risposta data 20.01.2011 - 11:42
fonte