web-dev-qa-db-de.com

Ruby: Dateiverschlüsselung/-entschlüsselung mit privaten/öffentlichen Schlüsseln

Ich suche einen Algorithmus zur Dateiverschlüsselung/-entschlüsselung, der folgende Anforderungen erfüllt:

  • Algorithmus muss zuverlässig sein
  • Algorithmus sollte für ziemlich große Dateien schnell sein
  • Privater Schlüssel kann durch einen Parameter (z. B. Passwort) generiert werden
  • Der generierte private Schlüssel muss mit dem öffentlichen Schlüssel kompatibel sein (der öffentliche Schlüssel wird nur einmal generiert und in der Datenbank gespeichert)

Gibt es eine Ruby-Implementierung von vorgeschlagenen Algorithmen?

20
tiktak

Hinweis: Wie in den Kommentaren erwähnt, ist diese Antwort für ein tatsächliches System nicht geeignet. Erstens sollte die Dateiverschlüsselung nicht mit dieser Methode durchgeführt werden (Die Bibliothek stellt beispielsweise AES bereit.). Zweitens wird in dieser Antwort keines der umfassenderen Probleme angesprochen, die sich auch auf die Art und Weise auswirken, wie Sie Ihre Lösung entwickeln.

Die ursprüngliche Quelle geht auch in weitere Details .

Ruby kann dafür openssl verwenden:

#!/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))

Und entschlüsseln:

#!/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))

von hier

31
brice

Ich befürchte, Sie mischen hier zwei Konzepte, Authentifizierung/Autorisierung und Vertraulichkeit, und versuchen, beide Aspekte in einem einzigen Schritt abzudecken, und das wird nicht funktionieren. Sie sollten niemals "echte Daten" mit asymmetrischen Algorithmen verschlüsseln. a) Sie sind dafür viel zu langsam. b) Es gibt subtile Probleme, die die Sicherheit Ihrer Lösung erheblich beeinträchtigen, wenn sie nicht richtig ausgeführt werden.

Eine gute Faustregel ist, dass das einzige, was Sie am Ende mit privaten asymmetrischen Schlüsseln verschlüsseln sollten, symmetrischen Schlüsseln ist, die von einem viel schnelleren symmetrischen Algorithmus verwendet werden. Aber in fast allen Fällen sollten Sie das gar nicht machen, denn in 90% der Fälle, die Sie tatsächlich wollen, ist TLS (SSL) in diesen Fällen - ich habe versucht zu erklären, warum hier vor einiger Zeit.

In Ihrem Fall gehe ich von folgenden Anforderungen aus:

  • vertraulichkeit der Daten, die in der Datenbank gespeichert werden sollen: Die Öffentlichkeit sollte nicht in der Lage sein, sie zu lesen (oder sogar darauf zuzugreifen).

  • einige ausgewählte Personen (wahrscheinlich nur eine Person) sollten auf diese Daten zugreifen und sie lesen können

Das erste Ziel wird im Allgemeinen durch die Verwendung von symmetrischer Verschlüsselung erreicht. Das zweite Ziel wird, wenn auch verwandt, auf ganz andere Weise verwirklicht. Sie möchten, dass der Benutzer, der auf die Datei zugreift, authentifiziert wird (d. H., Dass er die Identität festlegt) und dass er darüber hinaus autorisiert wird (d. H. Überprüft, ob die festgestellte Identität das Recht hat, das zu tun, was sie beabsichtigt). Hier betritt die asymmetrische Kryptographie darf die Bühne, aber nicht unbedingt. Da Ihre Frage mit Rails markiert ist, sprechen wir vermutlich über eine Rails-Anwendung. In der Regel haben Sie bereits einige Möglichkeiten, Benutzer dort zu authentifizieren und zu autorisieren (wahrscheinlich mit dem oben genannten TLS). Sie können diese einfach wiederverwenden, um einen symmetrischen Schlüssel für die tatsächliche Verschlüsselung/Entschlüsselung von Dateien zu erstellen. Passwortbasierte Verschlüsselung würde zu diesem Zweck passen, wenn Sie asymmetrische Verschlüsselung überhaupt vermeiden möchten. Noch komplizierter wird es, wenn Sie auch die Integrität der bereits vertraulichen Daten sicherstellen möchten, dh dem authentifizierten und autorisierten Benutzer eine Art Garantie geben möchten, in dem Sinne, dass das, auf das er letztendlich zugreift, in keiner Weise geändert wurde inzwischen.

Die Entwicklung einer Lösung für dieses Problem ist keine triviale Aufgabe und hängt in hohem Maße von Ihren Anforderungen ab. Ich fürchte, es gibt keinen "goldenen Weg", der für alle geeignet ist. Ich würde vorschlagen, etwas zu recherchieren, ein klareres Bild davon zu bekommen, was Sie erreichen möchten und wie, und dann zusätzliche Ratschläge zu Themen einzuholen, bei denen Sie sich immer noch unsicher/unwohl fühlen.

10
emboss

Ich habe einen Edelstein gemacht, der dabei hilft. Es heißt cryptosystem. Konfigurieren Sie einfach den Pfad und das Kennwort zu Ihrem privaten Schlüssel sowie den Pfad zu Ihrem öffentlichen Schlüssel, und der Rest wird erledigt.

Die Verschlüsselung ist so einfach wie:

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

Und entschlüsseln:

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

Sie können es auf GitHub oder RubyGems ausprobieren.

0
user6713635

Symmetric Encryption ist auf jeden Fall schnell und bietet hervorragende Unterstützung für das Streaming sehr großer Dateien.

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

Symmetric Encryption dient zum Verschlüsseln von Daten und großen Dateien in einer Organisation.

Wenn Sie Dateien für andere Organisationen freigeben möchten, ist PGP die beste Option. Zum Streamen sehr großer Dateien mit PGP beachten Sie: IOStreams

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

Weitere PGP-Beispiele finden Sie in der Datei iostreams/lib/io_streams/pgp.rb. Es unterstützt auch die PGP-Schlüsselverwaltung direkt von Ruby aus.

0
Reid