Qual è la prassi migliore per archiviare la chiave privata, il sale e il vettore di inizializzazione nel database?

6

Sto lavorando su un'applicazione java per creare una firma digitale per firmare un documento. Ho già creato la chiave privata e la chiave pubblica utilizzando ECC (crittografia a curva ellittica) e ora voglio memorizzare entrambe le chiavi nel database mysql.

Non ho alcun problema con la chiave pubblica, ma la mia preoccupazione è quella di memorizzare in modo sicuro la chiave privata.

Uso AES 128 bit per crittografare la chiave privata e la password a 6 cifre da utente a memorizzare nel database. Per crittografarlo, ho bisogno di generare sale e inizializzare il vettore.

Ma ora, per decodificarlo, devo anche conoscere lo stesso vettore di inizializzazione e di sale (iv) che uso per decifrare la chiave privata crittografata.

Domanda 1:

È sicuro memorizzare sale e vettoriale nella stessa tabella del database con la chiave privata? Attualmente codifico chiavi pubbliche e private, sale e iv e salva come stringa (tipo di dati VARCHAR) nel database.

Domanda 2:

Di seguito è riportato il flusso di lavoro corrente che progetto. È questa la migliore pratica? Non voglio fare troppi processi che influenzeranno l'utilizzo della CPU.

Creazione chiave

  • Crea una chiave privata utilizzando ECC
  • Codifica chiave privata (byte per stringa)
  • Cripta la chiave privata usando AES
  • Codifica chiave privata, salt, iv (Byte a Stringa)
  • Archivia nel database come VARHCAR

Firma del documento

  • Recupera la chiave privata dal DB
  • Decodifica chiave privata, salt, iv
  • Decrittografa la chiave privata
  • Decodifica chiave privata
  • Converti la chiave decodificata nella chiave privata effettiva per la firma

Snippet di codice per generare chiave e crittografia:

        //Generate salt
        Random r = new SecureRandom();
        byte[] salt = new byte[8];
        r.nextBytes(salt);
        //System.out.println("salt: "+salt);

        //initialize vector
        byte[] vector = new byte[128/8];
        r.nextBytes(vector);
        IvParameterSpec ivspec = new IvParameterSpec(vector);
        //System.out.println("iv: "+iv);

        //initialize variables
        String MsgToEncrypt = encodedECCprivateKeyBytes;
        String userPin = ParamUtil.getString(actionRequest, "userPin");
        Cipher ecipher;

        //Generating AES key
        SecretKeyFactory factory =  SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec mykeySpec = new PBEKeySpec(userPin.toCharArray(), salt, 10000, 128);
        SecretKey tmp = factory.generateSecret(mykeySpec);
        SecretKeySpec mySecretkey = new SecretKeySpec(tmp.getEncoded(), "AES");

        //==> Create and initiate encryption
        System.out.println("Initiate encryption alogrithm...");
        ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        //System.out.println("Algorithm to encrypt private key: " + ecipher);
        ecipher.init(Cipher.ENCRYPT_MODE, mySecretkey, ivspec);
        //System.out.println("SecKey: "+mySecretkey);
    
posta Mohamad Raziman Md Dom 19.01.2018 - 18:00
fonte

2 risposte

7

Risponderò alla tua domanda in due parti da quando la chiedi in due parti:

Question 1: Is it secure to store salt and vector in database same table with private key? Currently I encode public and private keys, salt and iv and save as string (data type VARCHAR) in database.

Risposta breve: Sì, è sicuro.

Spiegazione: è generalmente accettato che mantenere il sale in testo semplice insieme alla password con hash sia sicuro. Ciò si basa sulla logica che se un attaccante ha il sale e l'hash, devono comunque utilizzare un attacco di forza bruta per tentare di indovinare la password utilizzata per creare l'hash. Mantenere segreto il sale migliorerebbe anche la sicurezza ma fintanto che la password è ragionevolmente strong, non è necessario. Per il IV, è molto più complicato ea mio avviso fuori portata per entrare qui (e fuori dalla mia zona di comfort per spiegare) ma è considerato sicuro per l'IV essere memorizzato in testo semplice vicino al codice- testo.

Question 2: Below is current workflow I design. Is this the best practice? I don't want to make too much process that will affect CPU usage.

Il flusso di lavoro mi sembra buono ed è più o meno come avrei fatto io, con alcuni dettagli penso che tu possa migliorare dal momento che stai chiedendo le migliori pratiche:

  1. Innanzitutto, il tuo sale è un po 'troppo corto. Il problema con questo è che con un sale di 8 byte, anche se generato usando un generatore cripto-casuale (come sei tu, che è buono) c'è la possibilità di collisioni dove due o più utenti diversi hanno lo stesso valore di sale. Per mitigare questo, la raccomandazione che seguo è una lunghezza salt di 256 bit o 32 byte.

  2. Secondo consiglio e non sono sicuro sulla base del tuo codice se ne sei già a conoscenza, ma assicurati di non riutilizzare mai la stessa IV con lo stesso tasto AES due volte. A causa della crittanalisi molto sofisticata, questo può creare vulnerabilità nella crittografia rendendola fragile. Poiché la chiave viene generata da una password utente che presumo viene raramente modificata, assicurati di ruotare l'IV ogni volta che re-crittografate la chiave privata.

  3. Sembra che stiate facendo solo 10.000 round di hashing al momento. Sebbene questo non sia orribile, la regola d'oro che ho sempre seguito è l'iterazione 2 ^ (anno 2000). Dal momento che è il 2018, le migliori pratiche sono le 250.000 iterazioni o il valore più vicino a questo valore che si può ottenere prima di raggiungere i severi problemi di prestazioni.

In caso contrario, penso che tutto sia a posto, hai fatto una buona scelta nell'hashing e negli algoritmi chiave pubblico-privato e sei stato saggio a cercare aiuto per assicurarti di non aver trascurato nulla.

Spero che ti aiuti!

    
risposta data 19.01.2018 - 19:39
fonte
3

Sì. È sicuro memorizzare Salt e IV accanto alla voce crittografata.

Per capire perché, devi scavare proprio ciò che sono destinati a fare Salt e IV.

Salt è inteso come un modo per farlo in modo che se la voce one sia decifrata, essa non si ridurrà a nessun'altra voce. Se si disponesse di una tabella di password crittografate che non era hash, non appena qualcuno ha infranto un record, avrebbero anche eseguito il crack simultaneo di tutti i record che condividevano la stessa password decrittografata. Il sale non ha lo scopo di rendere più difficile la forza bruta; è pensato solo per garantire che ogni voce sia isolata dal punto di vista della cifratura da ogni altra voce. Quindi non importa se l'attaccante conosce la voce sale per ogni dato record, a patto che usi un sale diverso per ogni voce, il Salt sta facendo il suo lavoro.

Allo stesso modo, l'IV è pensato per fermare gli Attacchi in chiaro in chiaro. Ha lo scopo di impedire a qualcuno di sfruttare "Queste voci X condividono contenuti simili in byte X-Y" e utilizzando la crittanalisi per dedurre aspetti della chiave. Il IV fondamentalmente mescola i dati prima che vengano crittografati. Quindi conoscere la IV non aiuta l'attaccante a uscire.

Quindi vai avanti e archivia IV e Salt accanto al valore crittografato.

    
risposta data 19.01.2018 - 21:23
fonte