问题
My organization has decided to encrypt certain data in our database, and I've been given the task of implementing the encryption. I need to be able to encrypt the data, store the encrypted version in a VARCHAR field in our database, and later retrieve it and decrypt it back to its usual state.
On the surface it seems like a simple task. There are a number of ways to implement encryption. One I've used before is based on the AES encryption code found in this StackOverflow question.
What makes it harder in this case, is I need to write code to encrypt/decrypt the data in various applications that access our database, some of which are developed using different technologies. We have applications written in Coldfusion 5, in Classic ASP, and in ASP.NET 2.0. I need to be able to encrypt data and store it in the database with Coldfusion code, and then read and decrypt it back to its original form in ASP.NET. Or encrypt it in Classic ASP and decrypt it in Coldfusion. Or any other combination of these platforms.
This has proven to be harder than I expected. Different classes/objects/functions/libraries that claim to use the same algorithms seem to generate different results even when given the same data and the same shared secret. In the past, we've used CAPICOM to provide encryption interoperability between Coldfusion and Classic ASP. But I've run into trouble trying to get that to work in ASP.NET. I've read this article about how to get CAPICOM to work in .NET, but the suggestions haven't been working for me. I can't even seem to generate an interop class or import a reference to the COM object without getting an error. Also some of our production servers have operating systems that don't appear to be compatible with CAPICOM, so that may be a dead end anyway.
Does anyone have any suggestions as to how I can implement encryption in such a way that any of the 3 platforms can decrypt what the others have encrypted, while still using a reasonably-strong algorithm?
Edit 2011-12-29:
As noted in the comments below, I am currently hoping to find an ASP.NET solution that is compatible with some of our existing Coldfusion/ASP Classic code that uses CAPICOM. The reason for this is that our team lead doesn't want me to introduce a new encryption method into our code for our current purpose unless I also revise our older apps using encryption for a different purpose to use the same method. He wants to use the same encryption method for both purposes. Since revising our old apps to use a new encryption method means not just changing the code, but also tracking down all the data encrypted by the older apps, decrypting it, and re-encrypting it using the new method, I'm hesitant to go that route unless I have to. Hopefully, I'll find a way to get ASP.NET to read the existing encrypted data.
The encrypted data from our other Coldfusion and ASP Classic applications was encoded using the CAPICOM COM object. As far as I can tell, the settings have universally been AES encryption, maximum key size (which I believe is 256-bit in AES).
At @Leigh's request, here is a simplified example of how our existing CF apps use 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>
回答1:
Since you have the common database platform between all of the systems, I would leave your encryption/decryption there. Here's an article about column-specific encryption within SQL 2005:
http://msdn.microsoft.com/en-us/library/ms179331(v=sql.90).aspx
回答2:
I just did a similar thing (encrypting between Classic ASP and ASP .NET, ignoring Coldfusion) and I came across CAPICOM several times too, but after a lot of toing and froing (and searching) I found a COM AES/Rijndael library which I ended up using, Hyeongryeol.Security.Cryptography (for some reason the download is named .wma - it is a zip file so manually open it with 7-Zip or whatever you use).
Encryping/decrypting in .NET uses the RijndaelManaged class (there's an example in the download).
All-in-all it's very simple to get working. Just register the COM DLL (for Classic ASP) and it should be good to go. Here's an extract from our build.bat which ensures (hopes) it's registered:
echo Registering HyeongryeolStringEncrypter.dll
copy Libraries\Hyeongryeol.Security.Cryptography\ASP\HyeongryeolStringEncrypter.dll %system32%\HyeongryeolStringEncrypter.dll
regsvr32 /s %system32%\HyeongryeolStringEncrypter.dll
Just make sure you use the same key/IV either side.
回答3:
After an extensive search on multiple sites, others suggesting SSO but obviously with limitations, I came to the code below which allowed me what I wanted.
- We have an existing CF site and we are redesigning it using ASP.NET and Membership provider.
- We wanted to keep the passwords from existing CF but transfer them to aspnet_membership table, and hash them.
- We also wanted to be able to change password from either system as they will run concurrently for at most 3 months.
- This means we wanted to be able to update the aspnet_membership table from CF and to also authenticate against that table.
The below code allows us to hash the password from CF and match it against the aspnet_membership table. If theBased64Hash is the same as password in the table, then the user can be authenticated. We can now encrypt the password should the user want to change the password from the CF side, and still be validated in ASP.NET side.
Update (Fixed issue with concatenation)
<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>
回答4:
Encryption is just modifying your data so that its not human readable then modify it back using the reverse of the original formula.
I personally would stick with AES and you should be able to get AES for those platforms.
Depending on how strong you want it to be, you could just write a simple function to do it your self.
Could be as simple as adding a series of bits to the info based on some key.
来源:https://stackoverflow.com/questions/8661929/how-can-i-implement-strong-reversible-encryption-that-inter-operates-between-as