17

Cerco un algoritmo per il file di cifratura/decifratura che soddisfi i seguenti requisiti:Rubino: la crittografia dei file/decifratura con/chiavi pubbliche private

  • algoritmo deve essere affidabile
  • algoritmo dovrebbe essere veloce per un po ' file di grandi dimensioni
  • chiave privata può essere generato da alcuni parametri (ad esempio, password)
  • chiave privata generata deve essere compatibile con la chiave pubblica (chiave pubblica viene generato solo una volta e memorizzati nel database)

Esiste un'implementazione di algoritmi suggeriti da Ruby?

risposta

26

Nota Bene: Come rilievo menzioni nei commenti, questa risposta è una misura povero per un sistema vero e proprio. In primo luogo, la crittografia dei file non dovrebbe essere eseguita usando questo metodo (La lib fornisce AES, per esempio.). In secondo luogo, questa risposta non affronta nessuno dei problemi più ampi che influenzeranno anche il modo in cui si progetta la propria soluzione.

La fonte originale va anche a more details.

Rubino può usare OpenSSL per fare questo:

#!/usr/bin/env ruby 

# ENCRYPT 

require 'openssl' 
require 'base64' 

public_key_file = 'public.pem'; 
string = 'Hello World!'; 

public_key = OpenSSL::PKey::RSA.new(File.read(public_key_file)) 
encrypted_string = Base64.encode64(public_key.public_encrypt(string)) 

e decifrare:

#!/usr/bin/env ruby 

# DECRYPT 

require 'openssl' 
require 'base64' 

private_key_file = 'private.pem'; 
password = 'boost facile' 

encrypted_string = %Q{ 
... 
} 

private_key = OpenSSL::PKey::RSA.new(File.read(private_key_file),password) 
string = private_key.private_decrypt(Base64.decode64(encrypted_string)) 

da here

+2

In realtà non sono Rubyist, ma quelle sono batterie piuttosto buone. Mi chiedo quanto sia difficile l'equivalente in Python ... – brice

+3

Voglio solo aggiungere che i file dovrebbero essere ecnrypted con, ad esempio, AES-256, ma la sua chiave dovrebbe essere inviata con rsa. – tiktak

+4

Mi dispiace, ma questo è davvero un cattivo consiglio. L'OP parla della crittografia/decrittografia dei file e non si dovrebbe mai usare RSA per questo. – emboss

10

temo si stia mescolando due concetti qui, l'autenticazione/autorizzazione e riservatezza, cercando di coprire entrambi gli aspetti in un'unica fase, e ciò non funzionerà. Non si dovrebbe mai crittografare "dati reali" con algoritmi asimmetrici. a) sono troppo lenti per questo, b) ci sono problemi delicati che, se non eseguiti correttamente, indeboliranno gravemente la sicurezza della soluzione.

Una buona regola generale è che l'unica cosa che si dovrebbe finire la cifratura con privati ​​asimmetrici chiavi è simmetriche chiavi usate da un algoritmo molto più veloce simmetrica. Ma in quasi tutti i casi non dovresti nemmeno farlo, perché nel 90% dei casi quello che vuoi veramente è TLS (SSL) in questi casi - ho provato a spiegare perché qualche tempo fa lo here.

Nel tuo caso, suppongo che i requisiti sono:

  • la riservatezza dei dati che devono essere memorizzati nel database: il pubblico in generale non dovrebbe essere in grado di leggere (o anche accedervi)

  • un selezionato alcuni (probabilmente una sola persona) dovrebbe essere in grado di accedere e leggere i dati

Il primo obiettivo è generalmente ottenuto utilizzando 012.. Il secondo obiettivo è, benché correlato, realizzato con mezzi abbastanza diversi. Si desidera che l'utente acceda al file da autenticare (cioè, stabilisce l'identità) e in aggiunta si desidera che siano autorizzati (ad es.verificare se l'identità stabilita ha il diritto di fare ciò che intendono). È qui che la crittografia asimmetrica può entrare nello stage, ma non necessariamente. Dal momento che la tua domanda è taggata con Rails presumo che stiamo parlando di un'applicazione Rails. In genere si dispone già di mezzi per autenticare e autorizzare gli utenti (molto probabilmente con il suddetto TLS), è possibile semplicemente riutilizzarli per stabilire una chiave simmetrica per la crittografia/decrittografia dei file effettivi. Password-based encryption si adatta a questo scopo, se si desidera evitare la crittografia asimmetrica. Le cose diventano ancora più complicate se si vuole anche garantire l'integrità dei dati già riservati, cioè si vuole dare una sorta di garanzia all'utente autenticato e autorizzato nel senso che ciò che finalmente accede non è stato alterato in alcun modo nel frattempo.

Sviluppare una soluzione per questo non sarà un compito banale e dipenderà in larga misura dalle vostre esigenze, quindi temo che non ci sia una "via d'oro" adatta a tutti. Vorrei suggerire di fare qualche ricerca, ottenere un'immagine più chiara di ciò che stai cercando di ottenere e di come, quindi cercare di ottenere ulteriori consigli su argomenti che ti senti ancora incerto/a disagio.

+1

Grazie per la risposta!Ho risolto la domanda con il trasferimento e la memorizzazione dei dati nel modo seguente: 1) generare la chiave di crittografia simmetrica (sym-key) 2) crittografare i file con sym-key 3) crittografare sym-key con public asym-key 4) inviare file e crittografati sym-key 5) decifrare la chiave asimmica privata crittografata dell'utente con il token segreto dell'utente 6) decifrare la chiave sim ricevuta con la chiave privata asym-key 7) decrittografare i file con la chiave sim decrittografata. Penso sia piuttosto normale. – tiktak

+2

Questa è la direzione giusta! Ma è ancora vulnerabile agli attacchi di riproduzione. Invece di inviare una chiave avvolta da una chiave asimmetrica, non potresti usare TLS? Ho scoperto che in quasi tutti i casi in cui si trasportano dati da A a B si dovrebbe utilizzare TLS anziché crypto asimmetrico - TLS ti protegge contro le cose che molto probabilmente infrangerebbero un protocollo personalizzato. – emboss

0

Ho fatto una gemma per aiutare con questo. Si chiama cryptosystem. Basta configurare il percorso e la password della propria chiave privata, nonché il percorso della propria chiave pubblica, e fa il resto.

crittografia è semplice come:

rsa = Cryptosystem::RSA.new 
rsa.encrypt('secret') # => "JxpuhTpEqRtMLmaSfaq/X6XONkBnMe..." 

e decifrare:

encrypted_value = rsa.encrypt('secret') # => "Y8DWJc2/+7TIxdLEolV99XI2sclHuK..." 
rsa.decrypt(encrypted_value) # => "secret" 

È possibile controllare sul GitHub o RubyGems.

0

Symmetric Encryption è decisamente veloce e ha un eccellente supporto per lo streaming di file di grandi dimensioni.

SymmetricEncryption::Writer.open('my_file.enc') do |file| 
    file.write "Hello World\n" 
    file.write "Keep this secret" 
end 

Symmetric Encryption è progettato per crittografare dati e file di grandi dimensioni all'interno di un'organizzazione.

Quando si tratta di condividere file con altre organizzazioni, l'opzione migliore è PGP. Per lo streaming di file molto grandi con PGP considerare: IOStreams

IOStreams.writer('hello.pgp', recipient: '[email protected]') do |writer| 
    writer.write('Hello World') 
    writer.write('and some more') 
end 

Guarda le iostreams di file/lib/io_streams/pgp.rb per ulteriori esempi PGP. Supporta anche la gestione delle chiavi PGP direttamente da Ruby.