Firma i dati più grande di quanto consentito RSA Dimensione blocco?

3

Ho riscontrato un piccolo problema durante l'implementazione di una versione modificata di Protocollo Station-to-Station (STS). Supponiamo di avere due principal A e B, in cui entrambi conoscono la chiave pubblica dell'altro:

  1. A- > B: Ta (valore pubblico DH)
  2. B- > A: Tb, SigB (Tb, Ta, A)
  3. A- > B: SigA (Ta, Tb, B)

Per il secondo messaggio di protocollo, voglio crittografare (usando la mia chiave privata) alcuni dati usando la crittografia a chiave pubblica (ad esempio RSA); e siccome STS è un protocollo di accordo chiave utilizzato per stabilire una chiave segreta, non è possibile utilizzare la crittografia simmetrica come AES o 3DES.

Inoltre, ho pensato di eseguire l'hashing dei dati su alcune dimensioni fisse (usando, ad esempio, SHA-1) e quindi firmarlo; tuttavia, ciò non funzionerà, dal momento che l'altra parte deve essere in grado di estrarre le diverse parti del messaggio firmato per alcuni controlli di verifica successivi.

Nel caso non fossi chiaro: SigB(Tb,Ta,A) dove SigB significa signing utilizzando la chiave privata B, e io devo essere in grado di recuperare Ta, Tb e A.

C'è un altro modo oltre a ridurre i dati in blocchi e quindi firmare ciascun blocco (ECB, che è vulnerabile all'analisi crittografica)?

Ecco il codice che genera DHparamspec .

protected AlgorithmParameterSpec generateParameters() {
    DHParameterSpec spec = null;
    try {
        AlgorithmParameterGenerator apg = AlgorithmParameterGenerator
                .getInstance("DH");
        apg.init(1024);
        AlgorithmParameters algParam = apg.generateParameters();
        spec = (DHParameterSpec)algParam
                .getParameterSpec(DHParameterSpec.class);


    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidParameterSpecException e) {
        e.printStackTrace();
    }
    return spec; // something went wrong
}

E il codice che genera la coppia DH.

kf = KeyFactory.getInstance("DH");
            keyGen = KeyPairGenerator.getInstance("DH", "BC");
            keyGen.initialize(paramSpec);

            keyPair = keyGen.generateKeyPair();

            kAgreement = KeyAgreement.getInstance("DH");
            kAgreement.init(keyPair.getPrivate());
    
posta me_L_coding 30.07.2012 - 21:02
fonte

2 risposte

4

Woah. Questo è un po 'un casino. Facciamo un piccolo passo alla volta.

Prima di tutto: non dovresti progettare o implementare il tuo protocollo crittografico. Per favore non prenderlo personalmente, ma: non sei qualificato. E anche coloro che sono qualificati tentano di evitare di farlo, perché è così facile commettere errori impercettibili. Non caricare la tua crittografia .

Invece, dovresti usare TLS. Basta usarlo; è ben controllato, ci sono molte implementazioni ampiamente disponibili e risolve il tuo problema. Non c'è una buona ragione per implementare qualcos'altro e ogni ragione per evitare di farlo. Ci sono voluti molti anni e innumerevoli persone-decenni di tempo esperto per appianare le rughe e i problemi di sicurezza in TLS. Semplicemente non puoi permetterti di farlo per il tuo protocollo e il tuo codice personale. Non dovresti nemmeno provarci: dovresti riutilizzare lo sforzo che è stato già inserito in TLS.

Utilizza TLS. Problema risolto. Ora puoi passare il tuo tempo a qualcosa di più utile!

(Per rispondere alla domanda che hai effettivamente posto, se vuoi firmare un messaggio lungo, il metodo standard è quello di cancellarlo per primo con un hash resistente alle collisioni e firmare l'hash, anzi, questa tecnica è già presente in ogni pubblico -key schema di firma che abbia mai visto, quindi non è necessario fare qualcosa di speciale: già fanno l'hashing. [Spero davvero che tu non stia cercando di fare la firma RAA raw senza alcuna spaziatura, che è orribilmente insicuro. ] Non riuscivo a dare un senso alla tua spiegazione, non puoi semplicemente usare gli algoritmi di firma digitale standard, sospetto che tu possa esserti confuso o ti sei fatto intrecciare in nodi o qualcosa del genere, ma in ogni caso questo è tutto irrilevante: tu non dovresti progettare o implementare la crittografia a questo livello di astrazione Il modo migliore per rispondere alla tua domanda è di non-chiedere la domanda e indirizzarti verso una direzione diversa.)

    
risposta data 31.07.2012 - 08:51
fonte
2

RSA non è uno schema di firma . È solo un componente di uno schema di firma. Gli schemi di firma o crittografia effettivi basati su RSA includono anche padding : invece di applicare l'operazione RAA non elaborata ( m m d mod n o < em> m ↦ m e mod n ) al messaggio, si applica al concatenazione di alcuni testi di riempimento e del messaggio. Questo riempimento ha due ruoli principali:

  • Assicura che l'operazione RSA non venga applicata a un numero troppo piccolo. Questo impedisce a un numero di relazioni matematiche di infrangere la sicurezza dell'uso di RSA, il più semplice è che se si calcola m e mod n con entrambi m e e piccoli, non viene effettivamente eseguita alcuna riduzione del modulo.
  • Assicura che l'operazione RSA non venga mai applicata due volte allo stesso messaggio. Per la crittografia, questo impedisce a un utente malintenzionato di violare il messaggio con la forza bruta (provando ogni possibile testo in chiaro). Per le firme, ciò impedisce il sorgere di un certo numero di relazioni matematiche quando i relativi messaggi sono firmati.

Per ulteriori informazioni approfondite sul ruolo del padding, vedi È RSA di un nonce casuale senza padding sicuro? Il padding RSA deve essere imprevedibile se il payload è? È necessario il padding RSA per un singolo messaggio casuale, un unico messaggio casuale?

Esistono due schemi di riempimento comuni per le firme RSA: RSA-PSS e RSA-PKCS1.5. Entrambi sono definiti dal documento PKCS # 1 che definisce RSA. Non li spiegherò qui, leggi il documento PKCS # 1 per la loro definizione Entrambi i metodi richiedono che il messaggio sia il primo hash con una funzione di digest crittografico come SHA-256 o SHA-512 (o il loro predecessore SHA -1 ). Così una vera e propria firma RSA di un messaggio arbitrario¹ si presenta così:

RSA(key, message) = RSA_operation(key, padding ++ hash(message))

L'hash comprime le informazioni rilevanti sul messaggio (ovvero se un messaggio presunto è uguale al messaggio originale) in una dimensione limitata. Quando si esegue la crittografia, tale compressione non è possibile. Per crittografare dati di dimensioni arbitrarie con RSA, il solito metodo consiste nel generare una chiave segreta casuale (spesso chiamata chiave di sessione), crittografare il messaggio effettivo con quella chiave e inviare la chiave segreta crittografata con RSA. Vedi Come posso usare la crittografia asimmetrica, come RSA, per crittografare una lunghezza arbitraria di testo in chiaro?

¹ Tecnicamente, ci sono dei limiti, ma in pratica non li eseguirai: SHA-1 e SHA-256 possono essere eseguiti fino a 2 61 -1 byte, da SHA-512 a 2 125 -1 byte.

    
risposta data 31.07.2012 - 20:59
fonte

Leggi altre domande sui tag