Domanda

Ciao questa è la stessa domanda che è stato chiesto a due anni fa:Java/JCE:Decifrare “lungo” messaggio cifrato con RSA

Ho avuto un grande array di byte e coppia di chiavi rsa, avviato dal valore di 1024.Utilizzando un sistema di crittografia rsa e indicare la dimensione della chiave è una forte esigenza, io non posso cambiarlo.Quindi non posso usare la crittografia simmetrica con asimmetriche di cifratura a chiave simmetrica.Io non è possibile utilizzare altri tasti.Ho avuto un array di byte e la necessità cifrato matrice di byte che devono essere restituiti.Mi chiedo se c'è qualche tool, in grado di gestire questo problema?

Ci dispiace per un gruppo amatoriale domanda, ma ho veramente bisogno di un aiuto.

È stato utile?

Soluzione

Come detto, la tua domanda ha una sola risposta, e che il "no".La crittografia RSA è un algoritmo che consente di crittografare i messaggi fino a una certa dimensione, che dipende dalla dimensione della chiave;con chiavi RSA a 1024 bit, e RSA come standard la descrive, la dimensione massima è di 117 byte, non di più.Non c'è modo per crittografare un grande messaggio con RSA da solo, e che un definito, per la matematica certezza.

Se si ha realmente bisogno per elaborare i messaggi più lunghi, quindi si necessariamente aggiungere qualcos'altro.In questo caso, per favore, si prega di, non provare a fare qualcosa di fantasia di propria ideazione con alcune oh-così-intelligente suddivisione dei dati in blocchi e simili.Questa via conduce alla morte.Si potrebbe produrre qualcosa che appare per compilare ed eseguire, ma che sarà invariabilmente debole in qualche modo, come quasi tutte le altre fatte in casa variazione di crittografia.Questo perché la sicurezza non può essere testato:non è un caso di "opere" o "non funziona".

Ben calpestata percorso di crittografia asimmetrica va così:

  1. Si seleziona una sequenza casuale di byte di alcuni della lunghezza desiderata, ad es.128 bit (che è di 16 byte).Let's call it K.
  2. È possibile crittografare K con la chiave pubblica RSA;questo produce E.
  3. Si cifrare il messaggio con K utilizza un algoritmo di crittografia simmetrica ("AES/CBC/PKCS5Padding").Dal momento che questa è una one-shot chiave, è possibile utilizzare un all-zeri IV.Questo produce un mucchio di byte, chiamiamolo F.
  4. Il messaggio cifrato è poi la concatenazione di E e F.

Decrittografia procede in ordine inverso:la RSA chiave privata viene utilizzata per recuperare K da E, poi K viene utilizzata per decrittografare F nel messaggio originale.La chiave K non è mai memorizzati da nessuna parte, e un nuova chiave K viene generato ogni volta (anche se si crittografa lo stesso messaggio due volte).Questo è importante, non cambia che se non si capisce che cosa si sta facendo (e se si, allora sai già che).

Dato quello che è stato il tuo stesso problema, si sono per fare qualcosa di più che "solo RSA".La procedura che ho descritto sopra è di circa il migliore "qualcos'altro" che si potrebbe venire con, la sicurezza.

Montaggio di alcuni elementi di crittografia in tale protocollo è un processo irto di insidie, in modo che si possa avere più fortuna utilizzando un già definito il formato e il supporto della libreria.Due formati comuni per la crittografia asimmetrica sono CMS e OpenPGP.Una libreria che supporta entrambi e ha una buona reputazione è Castello Gonfiabile.

Altri suggerimenti

Se si ha bisogno di cifrare / decifrare lunghe stringhe utilizzando RSA, allora si può rompere i byte fino a piccoli "pezzi" e elaborare ogni pezzo di byte attraverso il cifrario uno alla volta, mentre memorizzare i risultati in un ByteBuffer.

Codifica:

byte[] encData = null;
try {

    // create public key
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(key);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey pk = kf.generatePublic(publicKeySpec);

    Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    pkCipher.init(Cipher.ENCRYPT_MODE, pk);

    int chunkSize = 117; // 1024 / 8 - 11(padding) = 117
    int encSize = (int) (Math.ceil(data.length/117.0)*128);
    int idx = 0;
    ByteBuffer buf = ByteBuffer.allocate(encSize);
    while (idx < data.length) {
        int len = Math.min(data.length-idx, chunkSize);
        byte[] encChunk = pkCipher.doFinal(data, idx, len);
        buf.put(encChunk);
        idx += len;
    }

    // fully encrypted data     
    encData = buf.array();
} catch (Exception e) {
    e.printStackTrace();

Decodifica

Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsaCipher.init(Cipher.DECRYPT_MODE, rsaPk);

int chunkSize = 128;
int idx = 0;
ByteBuffer buf = ByteBuffer.allocate(data.length);
while(idx < data.length) {
    int len = Math.min(data.length-idx, chunkSize);
    byte[] chunk = rsaCipher.doFinal(data, idx, len);
    buf.put(chunk);
    idx += len;
}

// fully decrypted data
byte[] decryptedData = buf.array();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top