Genera e archivia in modo sicuro chiavi pubbliche / private su Android

6

Sto facendo un'applicazione web che distribuisce i dati crittografati con le chiavi pubbliche dei suoi clienti. In questo momento funziona per dispositivi dedicati che distribuisco da solo. Prima che vengano spediti, faccio lampeggiare la coppia di chiavi pubblica / privata nel firmware del dispositivo.

Tuttavia, dal momento che questo è il 2017, volevo anche creare un'applicazione Android per fare in modo che qualsiasi dispositivo Android si comportasse come uno dei dispositivi che vendevo, poiché questo è più semplice per i clienti. L'unico collo di bottiglia che sto vivendo è la distribuzione delle chiavi.

Posso generare una coppia di chiavi pubblica / privata sul dispositivo Android al primo avvio dell'app e archiviarli in modo sicuro nella memoria interna, ma devo trovare un modo per inviare la chiave pubblica generata del dispositivo Android al mio server, quindi il mio server può crittografare i dati con esso.

Il motivo per cui non posso semplicemente inviare la chiave pubblica come richiesta HTTP al mio server è che non voglio che qualcuno con un computer sia in grado di generare una coppia di chiavi pubblica / privata e inviarlo al mio server in grado di ricevere dati come. È molto facile decompilare le applicazioni Android o usare wireshark per scoprire l'url utilizzato per registrare nuove chiavi.

Se dovessi utilizzare in questo modo, come potrei verificare ai miei server che la richiesta provenga da un dispositivo Android legittimo?

    
posta CryptoGuy51 02.02.2017 - 21:18
fonte

2 risposte

4

Esattamente come afferma Limit, e grazie a questa risposta, il modo corretto sarebbe:

  1. Genera una coppia di chiavi per la crittografia sul tuo server di sviluppo

    openssl genrsa -des3 -out private.pem 2048

    openssl rsa -in private.pem -outform PEM -pubout -out public.pem

  2. Archivia la chiave pubblica nel codice dell'applicazione, non importa dove. Questo verrà utilizzato nella funzione al passaggio 5. Forse offuscare il codice per impedire l'alterazione del meccanismo di crittografia. (la crittografia eviterà solo le manomissioni in transito con qualcosa come il proxy di burp. Qual è la capacità smali di chiunque?)

  3. Genera una coppia di chiavi sul dispositivo (hai menzionato che avevi giù, ma nel caso qualcuno si chiedesse)

    public static KeyPair getKeyPair() {
    KeyPair kp = null;
    try {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(2048);
        kp = kpg.generateKeyPair();
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    return kp; 
    }
    
  4. Isolare le chiavi pubbliche e memorizzarle dove vuoi. Archivia la chiave privata nell'archivio protetto.

    KeyPair clientKeys = getKeyPair();
    publicKey = clientKeys.getPublic();
    
  5. Cripta la chiave pubblica del client con la chiave pubblica del dev incorporato in modo da poterla inviare a casa.

    public static String encryptToRSAString(String clearText, String publicKey) {
        String encryptedBase64 = "";
        try {
            KeyFactory keyFac = KeyFactory.getInstance("RSA");
            KeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKey.trim().getBytes(), Base64.DEFAULT));
            Key key = keyFac.generatePublic(keySpec);
            // get an RSA cipher object and print the provider
            final Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
            // encrypt the plain text using the public key
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encryptedBytes = cipher.doFinal(clearText.getBytes("UTF-8"));
            encryptedBase64 = new String(Base64.encode(encryptedBytes, Base64.DEFAULT));
        } catch (Exception e) {
            e.printStackTrace();
        }
            return encryptedBase64.replaceAll("(\r|\n)", "");
    }
    
risposta data 03.02.2017 - 01:27
fonte
0

Quindi potresti voler ricevere le chiavi solo dagli utenti registrati? L'autenticazione richiederà alla fine un segreto condiviso tra il tuo server e l'utente registrato. Con questo segreto, puoi provare a scambiare le chiavi usando un buon protocollo di scambio di chiavi, ad esempio EKE o protocollo simile. link

Tuttavia, se si ha il certificato SSL del server (e presumo che tu abbia), quando stabilisci la connessione con l'utente registrato, può inviarti la sua coppia pubblica in questo canale, perché è già una connessione crittografata. Considerato anche una migliore pratica per non sviluppare / implementare protocolli di sicurezza propri o anche conosciuti, quindi questa opzione è probabilmente migliore.

In base al certificato SSL del server intendo il certificato che è firmato dall'autorità della CA attendibile

    
risposta data 03.02.2017 - 02:04
fonte