Archiviazione sicura dei dettagli del conto bancario nel database

5

Sto sviluppando un servizio che coinvolgerà l'addebito diretto degli account dei clienti su una base di routine (settimanale, mensile, ecc.) e quindi avrò bisogno di memorizzare le loro informazioni (numero BSB / routing e numero di conto) nel mio database Sono molto preoccupato per la sicurezza, quindi il mio primo pensiero è stato quello di non archiviare queste informazioni, ma dopo aver letto molte altre domande su questo argomento, ho trovato una soluzione che penso funzionerà - ma mi piacerebbe eseguirla ti abbiamo passato per assicurarmi di non aver lasciato buchi di sicurezza.

Quando un utente si registra al servizio, creerà una coppia di chiavi pubblica / privata con la chiave privata con una passphrase fornita dall'utente (la password del proprio account). La password viene sottoposta a hash con bcrypt e le chiavi pubbliche e private sono memorizzate insieme all'hash della password nella tabella utente.

Creerò anche una singola coppia di chiavi pubblica / privata di amministrazione che verrà utilizzata quando è necessario elaborare un addebito diretto. La chiave pubblica sarà nota all'applicazione e al database, ma la chiave privata verrà mantenuta fuori dal server, in modo che i dati possano essere scaricati solo quando crittografati e quindi elaborati altrove. Un'alternativa al download quando crittografato sarebbe invece caricare la chiave privata nell'applicazione, decrittografare i dati solo per quella richiesta e quindi eliminare la chiave privata caricata - si tratta di un buco di sicurezza?

Quando un utente si registra per l'addebito diretto, il servizio accetta la chiave pubblica dell'utente e la chiave pubblica dell'amministratore e li crittografa utilizzando Caratteristica di più destinatari di GPG .

Per quanto ne so, questo copre le seguenti situazioni:

  • Se l'utente desidera visualizzare i dati, dovrà fornire la propria password per decrittografare le informazioni.
  • Se l'utente desidera aggiungere altri dati, non dovrà fornire la propria password poiché io uso solo la sua chiave pubblica.
  • Se l'amministratore vuole visualizzare i dati, dovrà scaricare le informazioni e decrittografarle, oppure caricare la propria chiave privata (vedi sopra).
  • Se l'utente cambia la sua password, dovrò semplicemente aggiornare la sua chiave privata. Se hanno dimenticato la loro password, l'unico modo per decrittografare i loro dati sarebbe attraverso la chiave privata dell'amministratore, ma dato che questo è tenuto fuori dal sito, i dati dovrebbero essere cancellati.

Ci saranno problemi se la coppia di chiavi di amministrazione dovesse mai essere compromessa (a parte l'ovvio) e dovevo generare una nuova coppia di chiavi di amministrazione e quindi ricodificare tutti i dati memorizzati?

Ci sono dei buchi di sicurezza in questo design? Non sono certo un esperto, ma ho cercato di fare del mio meglio nella ricerca di questo, e ora mi piacerebbe avere qualche input.

Ho anche cercato servizi come Customer Information Manager (CIM) di Authorize.net ma per quanto mi riguarda puoi vedere che devi utilizzare il loro servizio per raccogliere i pagamenti, quando invece abbiamo già stabilito il nostro commerciante per farlo a un tasso più conveniente, e quindi abbiamo solo bisogno di un servizio di archiviazione sicura delle informazioni.

Il servizio utilizzerà HTTPS e funzionerà su Ubuntu 12.04, con PHP e MySQL, se questo aiuta.

Ogni consiglio che puoi dare sarà molto apprezzato!

Grazie

    
posta mitchdav 01.07.2015 - 03:45
fonte

3 risposte

4

The password is hashed with bcrypt, and the public and private keys are stored alongside the password hash in the user table.

Memorizzare la chiave privata significa che un compromesso del database consentirebbe a un utente malintenzionato di decrittografare le informazioni bancarie. Potresti anche memorizzare le informazioni bancarie in testo semplice.

Perché esattamente le informazioni bancarie devono essere crittografate dalla chiave dell'utente? L'utente chiederà tali informazioni "per favore, dimmi il conto bancario di cui ti ho parlato prima?"

    
risposta data 01.07.2015 - 03:51
fonte
2

Ti consiglio di prendere in considerazione la possibilità di pagare una terza parte per la sicurezza, perché probabilmente sarà la soluzione più fiscalmente responsabile. Se gestisci personalmente i dati della carta di pagamento, sarai responsabile degli audit PCI, che possono essere molto costosi. E dopo il cambio di responsabilità imminente di ottobre 2015 (supponendo che tu sia negli Stati Uniti), l'anello più debole nella catena di pagamento sarà responsabile della copertura delle spese di frode. Se i tuoi sistemi vengono violati, verrai senza dubbio steso ad asciugare dalle banche, dai processori dei pagamenti e dalle vittime. Avresti i soldi per coprire questi tipi di perdite?

    
risposta data 01.07.2015 - 03:59
fonte
0

Sì, usa queste funzioni per crittografare & decrittografare i dati dal DB.

  static function encrypt($s) {
    $keyHex = getenv('APP_KEY');
    if (!$keyHex) {
      Yii::error ("Could not retrieve environment variable APP_KEY");
      return null;
    }
    $key = pack('H*', $keyHex); 
    $iv = mcrypt_create_iv(256/8); // 256 bit / 8 bit/byte = 32
    $cipherText = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $s, 'cbc', $iv);
    $cipherText64 = base64_encode($iv.$cipherText);
    return $cipherText64;
  }

  static function decrypt($s) {
    $keyHex = getenv('APP_KEY');
    if (!$keyHex) {
      Yii::error ("Could not retrieve environment variable APP_KEY");
      return null;
    }
    $key = pack('H*', $keyHex);
    $cipher = base64_decode($s); 
    $iv = substr($cipher, 0, 256/8);
    $cipher = substr($cipher, 256/8); // strip off IV from front
    $text = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $cipher, "cbc", $iv);
    $text = rtrim($text, "
  static function encrypt($s) {
    $keyHex = getenv('APP_KEY');
    if (!$keyHex) {
      Yii::error ("Could not retrieve environment variable APP_KEY");
      return null;
    }
    $key = pack('H*', $keyHex); 
    $iv = mcrypt_create_iv(256/8); // 256 bit / 8 bit/byte = 32
    $cipherText = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $s, 'cbc', $iv);
    $cipherText64 = base64_encode($iv.$cipherText);
    return $cipherText64;
  }

  static function decrypt($s) {
    $keyHex = getenv('APP_KEY');
    if (!$keyHex) {
      Yii::error ("Could not retrieve environment variable APP_KEY");
      return null;
    }
    $key = pack('H*', $keyHex);
    $cipher = base64_decode($s); 
    $iv = substr($cipher, 0, 256/8);
    $cipher = substr($cipher, 256/8); // strip off IV from front
    $text = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $cipher, "cbc", $iv);
    $text = rtrim($text, "%pre%"); // mcrypt leaves null padding on the text
    return $text;
  }
"); // mcrypt leaves null padding on the text return $text; }

Attualmente ricevono la chiave da una variabile di ambiente, quindi dovrai modificarli per ottenere la chiave dall'utente. Presumo che vorrai che l'utente digiti la password ogni & ogni volta che accedono ai loro dati bancari. Non è necessario utilizzare la crittografia pubblica / privata. Questo va bene solo per valori piccoli, ma i numeri di conto bancario sono probabilmente abbastanza piccoli. La chiave dovrebbe essere una stringa esadecimale di 64 caratteri, o una chiave da 32 byte o una chiave da 256 bit. Deve essere comunque sicuramente casuale. Se si lascia che l'utente fornisca una password e la trasformi in una chiave con una funzione di derivazione della chiave basata su password (PBKDF), allora qualcuno potrebbe forzare l'attacco del database.

    
risposta data 01.07.2015 - 06:46
fonte

Leggi altre domande sui tag