Si dovrebbe firmare e cifrare usando la stessa chiave? Gli Azure Training Labs stanno adottando questo approccio

8

Sto prendendo il laboratorio di Azure LoadBalancing with WCF e riconosco che mi è stato detto che è cattivo da un prospettiva di sicurezza, ma non sono sicuro se si applica qui.

Qualcuno può guardare questo codice e dirmi se devono essere usati certificati diversi nel codice di produzione?

public class RsaSessionSecurityTokenHandler : SessionSecurityTokenHandler
    {
        public RsaSessionSecurityTokenHandler(X509Certificate2 certificate)
        {
            List<CookieTransform> transforms = new List<CookieTransform>();
            transforms.Add(new DeflateCookieTransform());
            transforms.Add(new RsaEncryptionCookieTransform(certificate));
            transforms.Add(new RsaSignatureCookieTransform(certificate));
            this.SetTransforms(transforms);
        }

        public override ClaimsIdentityCollection ValidateToken(SessionSecurityToken token, string endpointId)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }
            if (String.IsNullOrEmpty(endpointId))
            {
                throw new ArgumentException("endpointId");
            }

            // in active cases where absolute uris are used check the all parts of the token's 
            // endpoint id and this endpoint's id for equality except the port number
            Uri listenerEndpointId;
            bool listenerHasUri = Uri.TryCreate(endpointId, UriKind.Absolute, out listenerEndpointId);
            Uri tokenEndpointId;
            bool tokenHasUri = Uri.TryCreate(token.EndpointId, UriKind.Absolute, out tokenEndpointId);
            if (listenerHasUri && tokenHasUri)
            {
                if (listenerEndpointId.Scheme != tokenEndpointId.Scheme ||
                    listenerEndpointId.DnsSafeHost != tokenEndpointId.DnsSafeHost ||
                    listenerEndpointId.AbsolutePath != tokenEndpointId.AbsolutePath)
                {
                    throw new SecurityTokenValidationException(String.Format("The incoming token for '{0}' is not scoped to the endpoint '{1}'.", tokenEndpointId, listenerEndpointId));
                }
            }
            // in all other cases, fall back to string comparison
            else if (String.Equals(endpointId, token.EndpointId, StringComparison.Ordinal) == false)
            {
                throw new SecurityTokenValidationException(String.Format("The incoming token for '{0}' is not scoped to the endpoint '{1}'.", token.EndpointId, endpointId));
            }

            return this.ValidateToken(token);
        }
    }
    
posta random65537 15.04.2011 - 05:07
fonte

5 risposte

5

Molti hanno indicato l'escrow chiave come motivo per separare la crittografia e le chiavi di firma. Molti hanno anche detto che questo uso condiviso delle chiavi va bene in questo caso particolare. Ma nessuno ha menzionato i problemi di crittografia nella condivisione delle chiavi sia per la firma che per la crittografia

Se si osservano gli standard ufficiali per la crittografia, la maggior parte di essi specifica che vengono utilizzate chiavi diverse per diversi algoritmi. Per i certificati X509, la parte di utilizzo della chiave ha controlli molto specifici per la chiave utilizzata. Ad esempio, NIST ha questo da dire sui tasti della curva ellittica:

ECDSA keys shall only be used for the generation and verification of ECDSA digital signatures.

La ragione di ciò è che se più algoritmi diversi sono usati con la stessa chiave, allora la sicurezza deve essere provata per la combinazione di tutti gli algoritmi insieme, anziché solo per un algoritmo. In caso contrario, un utente malintenzionato potrebbe utilizzare un algoritmo per produrre un valore che non è in grado di calcolare autonomamente per attaccare la sicurezza di un altro algoritmo.

Ad esempio, ipoteticamente, un protocollo di chiave d'accordo che firma valori remoti arbitrari potrebbe essere usato per simulare firme valide. O forse l'invio di una chiave pubblica da firmare potrebbe rivelare un valore utile nell'accordo sulla chiave d'accordo. O concretamente nel caso di RSA, non è stato usato se padding sicuro, l'invio di un valore da firmare può dare una decrittazione di un testo cifrato se viene utilizzata la stessa chiave.

Quindi, a meno che tu non possa essere molto certo che entrambi gli algoritmi di firma e crittografia possono effettivamente essere usati insieme con la stessa chiave, in modo sicuro, non dovresti farlo. Anche se sei molto sicuro, è una cattiva pratica crittografica. E se hai bisogno di seguire gli standard, non ti lasceranno comunque.

    
risposta data 16.08.2011 - 22:21
fonte
6

È buona pratica generale utilizzare due coppie di chiavi separate (e quindi certificati) per la firma e la crittografia. Mi sono appena rinfrescato sui motivi per cui:

  • Quando una chiave viene utilizzata per la crittografia, è spesso saggio affidarlo in modo che se è perso, il contenuto crittografato non è anche perso. Però, non ripudio associato con a il certificato di firma non è valido con più copie della coppia di chiavi in giro. Quindi non vuoi un impegno il certificato della firma. A partire dal Wikipedia

Questa è la migliore che abbia mai sentito. Un sacco di volte quello che mi viene detto è "fallo e basta", e dato che spesso si deve lavorare all'interno dei vincoli del PKI che si è costretti a usare, è una affermazione abbastanza giusta.

Personalmente, penso per un semplice PKI, unendo i due insieme - specialmente se si utilizzano le funzionalità di "crittografia" della chiave per qualcosa di simile a SSL - un tipo transitorio di crittografia per la sola comunicazione punto a punto - quindi la sicurezza il rischio non è così alto.

Tuttavia, a volte devi essere pronto a lavorare con qualsiasi PKI che arriva. Quindi se il codice ha codificato in modo rigido l'ipotesi che il certificato di crittografia e il certificato di firma siano sempre la stessa cosa, allora penso che tu abbia un problema di interoperabilità.

Come ultima cosa - sono un po 'confuso sul codice - presumo che "ValidateToken" esegua la convalida della firma sul token, giusto? Non può decifrare e convalidare la firma utilizzando la stessa coppia di chiavi ... la crittografia è per l'invio al titolare della coppia di chiavi, la firma serve per verificare le informazioni dal titolare della coppia di chiavi. Sta facendo solo una convalida della firma qui?

    
risposta data 18.04.2011 - 17:37
fonte
4

In questo scenario particolare , questa tecnica va bene.

Si utilizza la stessa chiave crittografica (in questo caso un certificato X.509) per crittografare. L'esempio che si menziona implementa un token di sessione (semplicemente parlando di un cookie protetto), che è condiviso tra più servizi web simili seduti dietro un servizio di bilanciamento del carico. Quindi la 'firma' (in questo particolare scenario) non ha l'obiettivo di sicurezza di fornire non ripudio, ma di autenticazione dell'origine dei dati, cioè capire se il token di sessione è stato creato da uno dei servizi peer.

Nota: in altri scenari, in cui la firma serve un obiettivo di non rifiuto, è necessario utilizzare materiale chiave separato (come indicato correttamente dalle altre risposte qui).

    
risposta data 16.08.2011 - 11:54
fonte
3

Can someone look at this code and tell me if different certificates should be used in production code?

In primo luogo, qualsiasi codice utilizzato per una funzione di sicurezza dovrebbe essere progettato, revisionato, implementato, riesaminato dal codice e testato prima di entrare in un ambiente di produzione. Solo perché il codice proviene da MSDN non significa che sia sicuro. Anche se decidi di utilizzare il codice come scritto, ti preghiamo di non saltare il disegno. Il design potrebbe aiutarti a notare problemi di sistema più ampi.

Poiché bethlakshmi e Rook hanno notato che il certificato viene utilizzato per la crittografia (riservatezza) e la firma digitale (identificazione e autenticazione). In generale, è necessario utilizzare diversi certificati (o chiavi) per diverse funzioni. O più semplicemente, un certificato dovrebbe essere usato solo per una funzione.

In questo caso, sembra ok utilizzare lo stesso certificato per entrambe le funzioni. Anche se una delle operazioni fallisce e il messaggio viene ancora inviato, non sembra che nessuna parte del certificato sia esposta a meno che RsaEncryptionCookieTransform o RsaEncryptionCookieTransform non siano corretti. E inviando un messaggio con una crittografia riuscita ma senza firma o firma ma nessun encypryption sembra ok.

Se decidi di utilizzare un certificato per entrambe le funzioni, assicurati di evidenziarlo nel piano di gestione delle chiavi e nel modello delle minacce.

    
risposta data 16.07.2011 - 01:53
fonte
1

Non c'è niente di sbagliato in questo approccio. È importante notare che encryption!=authentication . L'uso della crittografia non garantisce che il messaggio non sia stato manomesso, tuttavia firmando il messaggio è possibile fare questa garanzia.

    
risposta data 16.04.2011 - 19:20
fonte

Leggi altre domande sui tag