Ci sono diverse cose sottili che rendono questo sicuro. La più importante: non stai specificando una IV nel tuo codice, quindi verrà generato un valore casuale per te. Si noterà che non è possibile decodificare il testo cifrato nello stesso linguaggio di programmazione in questo modo.
Quindi è necessario fornire un IV esplicito per entrambe le implementazioni. Ma prima vi mostro il codice, un consiglio:
generazione chiave:
Blowfish opera su blocchi di 64 bit, la sua dimensione chiave varia, ma OpenSSL (che attualmente poteri sia cifrario node.js di Ruby e implementazione) utilizza 128 bit per impostazione predefinita, ovvero 16 byte.
Quindi la tua chiave viola due principi: il primo: è semplicemente troppo lungo. È la rappresentazione esadecimale di un hash SHA-1, che è 20 byte * 2 = 40 byte invece di 16. La maggior parte delle volte va bene, perché l'implementazione tronca i valori in modo appropriato, ma è qualcosa che dovresti non dipendere sopra.
Il secondo errore, molto più grave, è che si utilizza la rappresentazione esadecimale anziché i byte non elaborati: grande problema di sicurezza! I caratteri esadecimali non sono affatto casuali, quindi in effetti riducete l'entropia del vostro input a metà della lunghezza (perché i byte sottostanti erano casuali).
Un modo sicuro per generare chiavi casuali sta usando OpenSSL :: caso
key = OpenSSL::Random.random_bytes(cipher_key_len)
Un terzo errore è quello di mantenere la vostra chiave hard-coded nelle fonti. È una cattiva idea Il minimo da fare è archiviarlo altrove nel file system, dove l'accesso è strettamente limitato. Vedi anche my answer per un'altra domanda.La chiave deve essere archiviata fuori banda e caricata solo dinamicamente all'interno dell'applicazione.
Cipher:
Blowfish invecchia. È ancora considerato ininterrotto nel senso che forzare brutalmente è l'unico modo per romperlo. Ma uno spazio di ricerca di 2^64 non è irraggiungibile per gli aggressori intraprendenti. Quindi dovresti davvero passare ad AES.
Padding:
pastiglie OpenSSL utilizzando PKCS5Padding (noto anche come PKCS7Padding) di default. Ruby beneficia di questo e la mia scommessa è che node.js utilizza anche questo - quindi dovresti essere al sicuro su questo.
Ora alla soluzione di lavoro. Abbiamo bisogno di generare un IV, Blowfish richiede che sia 64 bit - 8 byte. Avrai bisogno di rbytes per ottenere numeri casuali sicuri nel nodo. L'IV può essere hardcoded nelle tue fonti (è informazione pubblica, nessun impatto sulla sicurezza) - ma deve essere lo stesso su entrambi i lati. Dovresti pregenerare un valore e usarlo sia per node.js che per Ruby.
/*node.js*/
var rbytes = require('rbytes');
var iv = rbytes.randomBytes(8);
/*see advice above - this should be out-of-band*/
var key = rbytes.randomBytes(16);
var encrypted = "";
var cipher = crypto.createCipheriv('bf-cbc', key, iv);
encrypted += cipher.update('text');
encrypted += cipher.final('hex');
Ora la parte di Ruby:
require 'openssl'
c = OpenSSL::Cipher::Cipher.new("bf-cbc")
c.encrypt
# should be out-of-band again
c.key = OpenSSL::Random.random_bytes(16)
# may be public but has to be the same for Ruby and node
iv = OpenSSL::Random.random_bytes(8)
c.iv = iv
e = c.update("text")
e << c.final
puts e.unpack('H*')[0]
E in rubino apparentemente 1.8.7 uscite \ 347 \ 232 \ 213 \ 006 \ 250; \ 207 \ 302 mentre 1.9.2 output \ xE7 \ x9A \ x8B \ x06 \ xA8; \ x87 \ xC2 –