2011-12-28 9 views
6

La mia organizzazione ha deciso di crittografare alcuni dati nel nostro database e mi è stato assegnato il compito di implementare la crittografia. Devo essere in grado di crittografare i dati, archiviare la versione crittografata in un campo VARCHAR nel nostro database, e successivamente recuperarla e decrittarla al suo solito stato.Come posso implementare una crittografia forte e reversibile che interagisca tra ASP.NET 2.0, Coldfusion 5 e Classic ASP?

Sulla superficie sembra un compito semplice. Esistono diversi modi per implementare la crittografia. Uno che ho usato prima è basato sul codice di crittografia AES trovato in this StackOverflow question.

Ciò che rende più difficile in questo caso, è la necessità di scrivere codice per crittografare/decodificare i dati in varie applicazioni che accedono al nostro database, alcuni dei quali sono sviluppati utilizzando tecnologie diverse. Abbiamo applicazioni scritte in Coldfusion 5, in ASP classico e in ASP.NET 2.0. Devo essere in grado di crittografare i dati e archiviarli nel database con il codice Coldfusion, quindi leggerlo e decodificarlo nella sua forma originale in ASP.NET. Oppure crittografalo in ASP classico e decrittalo in Coldfusion. O qualsiasi altra combinazione di queste piattaforme.

Questo ha dimostrato di essere più difficile di quanto mi aspettassi. Diverse classi/oggetti/funzioni/librerie che pretendono di utilizzare gli stessi algoritmi sembrano generare risultati diversi anche se vengono dati gli stessi dati e lo stesso segreto condiviso. In passato, abbiamo utilizzato CAPICOM per fornire l'interoperabilità della crittografia tra Coldfusion e Classic ASP. Ma ho avuto problemi a cercare di farlo funzionare in ASP.NET. Ho letto this article about how to get CAPICOM to work in .NET, ma i suggerimenti non hanno funzionato per me. Non riesco nemmeno a sembrare di generare una classe di interoperabilità o di importare un riferimento all'oggetto COM senza ottenere un errore. Inoltre, alcuni dei nostri server di produzione hanno sistemi operativi che non sembrano essere compatibili con CAPICOM, quindi potrebbe comunque essere un vicolo cieco.

Qualcuno ha qualche suggerimento su come posso implementare la crittografia in modo tale che una qualsiasi delle 3 piattaforme possa decrittografare ciò che gli altri hanno crittografato, usando comunque un algoritmo ragionevolmente forte?

Edit 2011-12-29:

Come notato nei commenti qui sotto, Attualmente sto sperando di trovare una soluzione ASP.NET che è compatibile con alcuni dei nostri ASP classico codice Coldfusion esistente/che utilizza CAPICOM. Il motivo è che il nostro team non vuole che introduca un nuovo metodo di crittografia nel nostro codice per il nostro scopo attuale, a meno che non modifichi anche le nostre vecchie app utilizzando la crittografia per uno scopo diverso per utilizzare lo stesso metodo. Vuole utilizzare lo stesso metodo di crittografia per entrambi gli scopi. Poiché rivedere le nostre vecchie app per utilizzare un nuovo metodo di crittografia significa non solo modificare il codice, ma anche rintracciare tutti i dati crittografati dalle vecchie app, decrittografarlo e ricodificarlo con il nuovo metodo, sono titubante quella via a meno che non sia necessario. Spero di trovare un modo per far sì che ASP.NET legga i dati crittografati esistenti.

I dati crittografati delle altre applicazioni Coldfusion e ASP Classic sono stati codificati utilizzando l'oggetto COM CAPICOM. Per quanto posso dire, le impostazioni sono universalmente state crittografia AES, dimensione massima della chiave (che credo sia 256 bit in AES).

A @ richiesta di Leigh, ecco un esempio semplificato di come le nostre applicazioni CF esistenti utilizzano CAPICOM:

<cfscript> 
    encryptObject = CreateObject("com","CAPICOM.EncryptedData"); 
    encryptObject.Algorithm.Name = 4; // 4 is AES 
    encryptObject.Algorithm.KeyLength = 0; // 0 is MAX, I believe 256-bit in the case of AES 
    encryptObject.SetSecret(sharedSecret); 
    encryptObject.Content = stringToEncrypt; 

    encryptedData = localScope.encryptObject.Encrypt(); 
</cfscript> 
+0

Si prega di prestare più attenzione alle vostre scelte tag. Il tag 'asp' si era dimostrato ambiguo, ed è stato ripulito a favore di' asp-classic'. Avresti avuto l'unica domanda su Stack Overflow tagged 'asp', e che avrebbe dovuto inviare una grossa bandiera rossa. –

+0

@Joel Le mie scuse. Non me ne sono accorto, ma guarderò con più attenzione in futuro. –

+0

Che tipo di prodotto database stai usando? –

risposta

6

Dal momento che avete la piattaforma di database comune tra tutti i sistemi, vorrei lasciare la cifratura/decifratura Là.Ecco un articolo sulla crittografia specifica colonna all'interno di SQL 2005:

http://msdn.microsoft.com/en-us/library/ms179331(v=sql.90).aspx

+0

Grazie! Questo è un solido suggerimento. Non avevo idea che fosse un'opzione. Ho intenzione di farlo funzionare dal team e vedere se qualcuno ha un problema con esso. –

+1

Basta non memorizzare la chiave nel database. –

+0

Questo è un buon suggerimento. L'ho gestito dal lead del progetto, però, e ha detto che era d'accordo con me che lo usava ** SE ** Ho modificato tutto il nostro codice di crittografia/decrittografia esistente per essere anche basato su SQL, quindi i nostri metodi sono coerenti. Ugh. Questo è ancora sul tavolo, ma sarà meno lavoro se riesco a trovare il codice ASP.NET che funziona bene con il metodo CAPICOM che abbiamo usato in CF e ASP classico in passato. Quindi continuerò a provarci per ora. –

2

Ho appena fatto una cosa simile (la crittografia tra il Classic ASP e ASP .NET, ignorando Coldfusion) e mi sono imbattuto in CAPICOM più volte troppo, ma dopo un sacco di toing and froing (e ricerca) ho trovato una libreria COM AES/Rijndael che ho finito usando, Hyeongryeol.Security.Cryptography (per qualche motivo il download è chiamato .wma - è un file zip quindi aprilo manualmente con 7-Zip o qualsiasi altra cosa tu usi).

La crittografia/decrittografia in .NET utilizza la classe RijndaelManaged (c'è un esempio nel download).

Nel complesso è molto semplice lavorare. Basta registrare la DLL COM (per Classic ASP) e dovrebbe andare bene. Ecco un estratto dal nostro build.bat che assicura (speranze) è iscritto:

echo Registering HyeongryeolStringEncrypter.dll 
copy Libraries\Hyeongryeol.Security.Cryptography\ASP\HyeongryeolStringEncrypter.dll %system32%\HyeongryeolStringEncrypter.dll 
regsvr32 /s %system32%\HyeongryeolStringEncrypter.dll 

Basta fare in modo di utilizzare la stessa chiave/IV entrambi i lati.

+0

Sono a conoscenza della classe 'RijndaelManaged', ma non sono sicuro di come farlo funzionare con le funzioni di crittografia a mia disposizione in ASP e CF. Ad esempio, una cosa che non capisco: nel nostro codice ASP classico esistente quando crittografiamo con CAPICOM, è sufficiente impostare i dati, il metodo di crittografia e la chiave. Ma la funzione 'CreateEncryptor' della classe RijndaelManaged richiede una chiave e un _vector_. Cos'è un vettore, perché CAPICOM non lo richiede e cosa posso passare a 'CreateEncryptor' che produrrà gli stessi risultati di CAPICOM? –

+0

Se si utilizza la DLL COM Hyeongryeol, non è necessario utilizzare CAPICOM. Hyeongryeol accetta sia un parametro chiave/IV (lo stesso di RijndaelManaged) che in tutti i miei test sono stato in grado di crittografare/decifrare le stringhe con successo sul lato ASP o ASP.NET e ottenere lo stesso risultato. – akiller

+0

Capito. Purtroppo abbiamo già alcune applicazioni che utilizzano CAPICOM e sarebbe ideale se la soluzione per questo progetto fosse compatibile. Cercherò di trovare un metodo di decrittografia ASP.NET che sia compatibile con il nostro codice CAPICOM esistente. Se non riesco a trovarne uno, cercherò la crittografia Hyeongryeol o basata su SQL Server. –

0

La crittografia modifica semplicemente i dati in modo che non siano leggibili da parte dell'utente, quindi li modificano utilizzando il retro della formula originale.

Personalmente aderirei ad AES e dovresti essere in grado di ottenere AES per quelle piattaforme.

A seconda di quanto vuoi essere forte, puoi semplicemente scrivere una semplice funzione per farlo da solo.

Potrebbe essere semplice come aggiungere una serie di bit alle informazioni basate su un tasto.

1

Dopo una ricerca estesa su più siti, altri che suggeriscono SSO ma ovviamente con limitazioni, sono arrivato al codice qui sotto che mi ha permesso quello che volevo.

  1. Abbiamo un sito CF esistente e lo stiamo riprogettando utilizzando ASP.NET e il provider di appartenenze.
  2. Volevamo mantenere le password dalla CF esistente ma trasferirle nella tabella aspnet_membership e cancellarle.
  3. Volevamo anche essere in grado di modificare la password da entrambi i sistemi poiché verranno eseguiti contemporaneamente per un massimo di 3 mesi.
  4. Ciò significa che volevamo essere in grado di aggiornare la tabella aspnet_membership da CF e anche di autenticarsi su quella tabella.

Il codice sottostante ci consente di cancellare la password da CF e confrontarla con la tabella aspnet_membership. Se Based64Hash è uguale alla password nella tabella, l'utente può essere autenticato. Ora possiamo crittografare la password se l'utente desidera modificare la password dal lato CF e continuare a convalidare in ASP.NET.

Aggiornamento (Risolto il problema con la concatenazione)

<cfscript> 
    thePassword = "originalPassword"; 
    base64Salt = "JZjdzUXREM0A7DPI3FV3iQ=="; 

    // extract bytes of the salt and password 
    saltBytes = binaryDecode(base64Salt, "base64"); 
    passBytes = charsetDecode(thePassword, "UTF-16LE"); 

    // next combine the bytes. note, the returned arrays are immutable, 
    // so we cannot use the standard CF tricks to merge them  
    ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils"); 
    dataBytes = ArrayUtils.addAll(saltBytes, passBytes); 

    // hash binary using java 
    MessageDigest = createObject("java", "java.security.MessageDigest").getInstance("SHA-1"); 
    MessageDigest.update(dataBytes);  
    theBase64Hash = binaryEncode(MessageDigest.digest(), "base64"); 

    WriteOutput("<br />theBase64Hash= "& theBase64Hash &"<br/>"); 
</cfscript> 
+0

Se possibile, è necessario passare a un algoritmo più sicuro. [CFMX_COMPAT] (http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c2f.html) è estremamente debole e incluso solo per compatibilità con le versioni precedenti. – Leigh

+0

Grazie a @Leigh per il codice di esempio. Funziona davvero per noi. Il motivo per cui è stato necessario utilizzare l'hash SHA1 era dovuto al controllo dell'appartenenza a ASP.NET. – SollyM

+0

Sì, il codice funziona. Non è molto sicuro. Da qui il suggerimento di passare a un algoritmo più forte ;-) – Leigh