Ich verwende Open SSL bindings von Ruby, um AES-256-Verschlüsselung zu tun. Ich kann eine nicht leere Zeichenfolge verschlüsseln. Beim Versuch, eine leere Zeichenfolge zu verschlüsseln, löst Ruby eine Ausnahme aus, in der es heißt, dass die Daten nicht leer sein dürfen. Wie kann ich eine leere Zeichenfolge mit den OpenSSL-Bindungen von Ruby verschlüsseln?Verschlüsseln leerer String
Code, um das Problem
require "openssl"
KEY = OpenSSL::Cipher::Cipher.new("aes-256-cbc").random_key
def encrypt(plaintext)
cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
cipher.encrypt
iv = cipher.random_iv
cipher.iv = iv
cipher.key = KEY
ciphertext = cipher.update(plaintext) # <- ArgumentError here
ciphertext << cipher.final
[iv, ciphertext]
end
def decrypt(iv, ciphertext)
cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
cipher.decrypt
cipher.iv = iv
cipher.key = KEY
plaintext = cipher.update(ciphertext)
plaintext << cipher.final
plaintext
end
p decrypt(*encrypt("foo")) # "foo"
p decrypt(*encrypt(""))
# /tmp/foo.rb:11:in `update': data must not be empty (ArgumentError)
# from /tmp/foo.rb:11:in `encrypt'
# from /tmp/foo.rb:27:in `<main>'
Versionen
- rubin 2.2.2p95
- OpenSSL :: VERSION ist "1.1.0"
- Microsoft SQL Server 2014 zu reproduzieren (12.0.2000.8)
Warum möchte ich leere Zeichenfolgen verschlüsseln?
Ich schreibe ein ETL Programm, um Daten von einer Datenbank in eine SqlServer-Datenbank zu migrieren. Bestimmte Spalten aus der Quelldatenbank müssen verschlüsselt werden, bevor sie in die Zieldatenbank geschrieben werden. Die Quellenspalten können beliebige Daten einschließlich leerer Zeichenfolgen enthalten. Die Zielspalten sind normalerweise nicht nullfähig. Die Zielspalten werden mit dem .net-Code entschlüsselt.
Ziel # 1: Keine Informationen über das verschlüsselte Feld, einschließlich, ob es überhaupt existiert oder nicht, sollten wiederhergestellt werden können, ohne es richtig zu entschlüsseln. Eine verschlüsselte leere Zeichenfolge sollte von anderen verschlüsselten Daten nicht zu unterscheiden sein.
Ziel # 2: Der .NET-Code, der diese Werte entschlüsseln wird, sollte nicht speziell mit leeren Zeichenfolgen umgehen.
Wenn ich openssl bekommen kann, um leere Zeichenfolgen zu verschlüsseln, werde ich diese beiden Ziele erreichen.
Umgehung - Verschlüsseln Sie keine leeren Zeichenfolge
Ich konnte einfach nicht leere Zeichenfolge verschlüsseln, so dass sie die Durchreise.
Dies hat die Nachteile der Offenlegung von Informationen und auch der Anforderung, dass kooperierender Code auf der .net-Seite geschrieben werden muss.
Umgehung - eine Konstante zu dem unverschlüsselten Text hinzufügen
ich zu dem unverschlüsselten Text vor der Verschlüsselung einen konstanten String hinzufügen könnte, und entfernen Sie es nach der Entschlüsselung:
PLAINTEXT_SUFFIX = " "
def encrypt(plaintext)
plaintext += PLAINTEXT_SUFFIX
...
end
def decrypt(iv, ciphertext)
...
plaintext.chomp(PLAINTEXT_SUFFIX)
end
Dies verbirgt, ob die Daten oder nicht vorhanden ist, erfordert aber immer noch die Zusammenarbeit mit .net-Code.
OpenSSL unterstützt PKCS # 7 Padding, so sollte dies funktionieren. Dies ist wahrscheinlich besser als Fehlerbericht geeignet. Übrigens, hast du schon versucht, 'cipher.update' zu überspringen, wenn der Klartext leer ist? 'cipher.final' könnte in diesem Fall ausreichend sein. –
@ ArtjomB. Ich hatte versucht, den Anruf zu Cipher # Update wegzulassen. Es hat nicht funktioniert, als ich es vorher aufgrund eines ID10T-Fehlers versuchte, als ich es zu der Zeit nicht bemerkte. Das ist die Lösung. Könnten Sie das bitte als Antwort hinzufügen? –
Sie können es selbst hinzufügen. Ich habe keine Ahnung von Rubin und möchte nicht zu diesem bestimmten Zeitpunkt anfangen zu lernen. :) –