Devi definire con una certa precisione cosa intendi per "chiave privata RSA".
In RSA, c'è un modulo , cioè un grande intero n che è uguale al prodotto di due numeri interi primi uguali chiamati p e q . Inoltre, c'è un esponente pubblico e (solitamente piccolo, tradizionalmente uguale a 65537 nel contesto di PGP) e un corrispondente esponente privato d . La dimensione di d è all'incirca uguale alla dimensione di n ; d è tale che e * d = 1 se preso modulo p-1 o q-1 .
La chiave pubblica consiste in n e e . L'operazione di chiave pubblica comporta l'elevazione di un intero alla potenza e modulo n . La chiave privata è tutto ciò che consente il calcolo dell'operazione inversa (trovando il e -th root modulo n ). Le seguenti serie di informazioni consentono di estrarre e -th root e quindi tutte possono essere considerate "la chiave privata":
-
n e d
-
p , q e d
-
p , q , d mod p-1 , d mod q-1
-
p , q e e
Quindi devi decidere cosa tu definisci come "chiave privata RSA" e di che "metà" stai parlando.
Vediamo cosa definisce OpenPGP . Nella sezione 5.5.3, vediamo che esiste un formato di archiviazione standard per le chiavi private RSA, nel contesto di OpenPGP. Questo formato memorizza la chiave pubblica ( n e e ), e anche d , p , q e un valore chiamato u , che è l'inverso di p modulo q (questo valore aiuta a implementare RSA in modo efficiente; essere ricalcolati sul posto, ma memorizzarli produce operazioni più veloci). In realtà p , q e e sono tutto ciò che può essere impostato, poiché gli altri valori possono essere calcolati deterministicamente da questi tre. E e è tradizionalmente impostato e dovrebbe comunque rimanere piccolo (per efficienza e interoperabilità). Quindi hai p e q per "nascondere" il valore preimpostato.
La generazione di chiavi RSA funziona grosso modo in questo modo:
- Genera un intero casuale p della dimensione giusta (metà della dimensione del modulo di destinazione).
- Verifica se p è primo. In caso contrario, riprova fino a quando non ottieni un primo.
- Genera q allo stesso modo. Assicurati che q sia nell'intervallo corretto in modo che n = pq abbia la dimensione target desiderata. Inoltre, OpenPGP richiede che q sia maggiore di p (se si ottiene un q più piccolo, è sempre possibile scambiarli).
Quindi potresti teoricamente modificare il processo in questo modo:
- Dividi il valore V che vuoi nascondere in due metà, V 1 e V 2 . Supponiamo che V 1 e V 2 abbiano lunghezza k (in bit) .
- Genera potenziali valori casuali p che includono " V 1 , ovvero p = 1 + 2 * V 1 + r * 2 k + 1 per valori interi casuali r della "dimensione giusta" in modo che p la lunghezza è, ad esempio, 512 bit (se si targetizza un modulo a 1024 bit). Riprova finché non premi un p di primo livello
- Fai lo stesso per q , incorporando V 2 .
Questo processo funzionerà fintanto che puoi avere r valori di dimensioni di almeno una dozzina di bit. Altrimenti, non ci potrebbe essere nessun primo con il formato desiderato. Il "* 2" e il "+1" sono lì per forzare p a essere dispari: un grande primo non può essere pari.
Non conosco alcun software che lo implementa, ma non dovrebbe essere difficile eseguire uno schiaffo con una libreria di numeri interi. Suggerisco di usare Java, che ha il java.math.BigInteger
appropriato, e poi Castello gonfiabile per la parte in formato encoding-into-OpenPGP.
Fai attenzione che un attaccante sapendo che giochi tali trucchi potrebbe provare ad attaccare la tua chiave sfruttando qualsiasi struttura abbia il tuo valore nascosto. Inoltre, implementare la tua crittografia è raramente una buona idea. E non dissi nulla sul fatto che la tua idea di "nascondere una chiave in bella vista" avesse senso; Ho solo mostrato come potrebbe essere fatto.