I have 2 websites: one written in classic asp and another written in ASP.NET (1.1 framework). Both applications use a login mechanism to validate user credentials based on a shared database table. Up to now passwords are stored in a 1-way MD5 hash, meaning people must be given a new generated password if they lose the old one. I now want to change this and make the passwords decryptable.
我有两个网站:一个是用经典的asp写的,另一个是用asp写的。净(1.1框架)。两个应用程序都使用登录机制来基于共享数据库表验证用户凭证。到目前为止,密码存储在1-way MD5哈希中,这意味着如果用户丢失了旧密码,就必须获得新的密码。现在我想要更改它并使密码可以解密。
I found this Rijndael code to use with classic asp: http://www.frez.co.uk/freecode.htm#rijndael
我发现这个Rijndael代码可以与经典的asp一起使用:http://www.frez.co.uk/freecode.htm# Rijndael
But I cannot find the same solution for ASP.NET. I tried this, but it gives me different encryption and decryption results between the classic asp and ASP.NET code:
但是我不能为ASP.NET找到相同的解决方案。我尝试了这个,但是它给了我不同的加密和解密结果在经典的asp和asp之间。NET代码:
If Not String.IsNullOrEmpty(TextBox1.Text) And Not String.IsNullOrEmpty(TextBox2.Text) Then
Dim password = TextBox1.Text
Dim key = TextBox2.Text
Dim keyGenerator = New Rfc2898DeriveBytes(key, 8)
Dim r = New RijndaelManaged
r.Mode = CipherMode.CBC
r.Padding = PaddingMode.Zeros
r.BlockSize = 256
r.KeySize = 256
r.FeedbackSize = 256
r.IV = keyGenerator.GetBytes(CType(r.BlockSize / 8, Integer))
r.Key = keyGenerator.GetBytes(CType(r.KeySize / 8, Integer))
Dim transform As ICryptoTransform = r.CreateEncryptor()
Dim encoded As Byte() = Encoding.ASCII.GetBytes(password)
Dim target As Byte() = transform.TransformFinalBlock(encoded, 0, encoded.Length)
TextBox3.Text = Encoding.ASCII.GetString(target)
End If
I think I'm doing something wrong with generating the key or iv, but I can't find a solution.
我认为我在生成钥匙或iv时做错了什么,但我找不到解决方案。
3 个解决方案
#1
0
I had a quick look at the classic asp files and it doesn't mention the block mode used, whereas your .net code specifies CBC mode and also the padding. Further the classic implementation states:
我快速浏览了一下经典的asp文件,它没有提到所使用的块模式,而.net代码指定了CBC模式和填充。进一步的经典实施状态:
' 3-Apr-2001: Functions added to the bottom for encrypting/decrypting large ' arrays of data. The entire length of the array is inserted as the first four ' bytes onto the front of the first block of the resultant byte array before ' encryption.
' 3-Apr-2001:添加到底部用于加密/解密大型数据数组的函数。数组的整个长度作为前四'字节插入到生成的字节数组的第一个块的前面,然后进行'加密'。
Are you using those functions, if you are then your encrypting the size bytes too.
您是否正在使用这些函数,如果您正在对大小字节进行加密。
Be assured the .net encryption works well, I'd guess your problem is in the classic solution you've found. If I were in your position I'd start by simplifying things and just encrypt a single block with each method and then expand from there... good luck
请放心。net加密工作得很好,我猜您的问题在您找到的经典解决方案中。如果我处在您的位置,我将从简化开始,用每个方法加密一个块,然后从那里展开……祝你好运
#2
4
Phil Fresle provides a C# version of this code downloadable here: http://www.frez.co.uk/csharp.aspx. The implementation is still different than the classic version as it takes arguments for an initialization vector as well as the block and key size.
Phil Fresle提供了这个代码的c#版本,可以在这里下载:http://www.frez.co.uk/csharp.aspx。该实现仍然与经典版本不同,因为它接受初始化向量以及块和键大小的参数。
You can use this implementation to match the classic version like so:
您可以使用这个实现来匹配经典版本如下:
// Convert the input values to byte[]'s representing ASCII encoding.
// This is what the classic version does
byte[] dataToEncrypt = ASCIIEncoding.ASCII.GetBytes("Ryno");
byte[] password = ASCIIEncoding.ASCII.GetBytes("Saurus");
// Encrypt the data into an array of types
// Notice the block size is 256 bits and the initialization vector is empty.
byte[] results = Rijndael.EncryptData(
dataToEncrypt,
password,
new byte[] { }, // Initialization vector
Rijndael.BlockSize.Block256, // Typically 128 in most implementations
Rijndael.KeySize.Key256,
Rijndael.EncryptionMode.ModeEBC
);
// Convert bytes into a HEX string representation
StringBuilder hex = new StringBuilder(results.Length * 2);
foreach (byte b in results)
hex.AppendFormat("{0:x2}", b);
// FINAL OUTPUT: This matches output of classic ASP Rijndael encryption
string hexEncodedString= hex.ToString();
Most default implementations will use a key size of 128, 192, or 256 bits. A block size at 128 bits is standard. Although some implementations allow block sizes other than 128 bits, changing the block size will just add another item into the mix to cause confusion when trying to get data encrypted in one implementation to properly decrypt in another.
大多数默认实现将使用128、192或256位的密钥。块大小为128位是标准的。虽然有些实现允许使用128位以外的块大小,但是更改块大小只会在混合中添加另一个项,从而在尝试在一个实现中加密数据以在另一个实现中正确解密时造成混乱。
Hopefully this helps.
希望这可以帮助。
Update
Phil's link is no longer available, so I've created a 2 Gists:
Phil的链接不再可用,所以我创建了两个gist:
- ASP / VB Implementation: https://gist.github.com/ryno1234/2fc83faff281babea7f8
- ASP / VB实现:https://gist.github.com/ryno1234/2fc83faff281babea7f8
- C# Implementation with helper class for ASP interop: https://gist.github.com/ryno1234/ea34415643d109974b6f
- c#实现与ASP接口的帮助类:https://gist.github.com/ryno1234/ea34415643d109974b6f
#3
0
Since ASP classic doesn't have native hash functions, you'll probably need to port your MD5 VBScript code to your .NET language, or to use a common cryptography component, due some error on your legacy code.
由于ASP classic没有本地哈希函数,您可能需要将MD5 VBScript代码移植到. net语言,或者使用公共加密组件,因为遗留代码有一些错误。
#1
0
I had a quick look at the classic asp files and it doesn't mention the block mode used, whereas your .net code specifies CBC mode and also the padding. Further the classic implementation states:
我快速浏览了一下经典的asp文件,它没有提到所使用的块模式,而.net代码指定了CBC模式和填充。进一步的经典实施状态:
' 3-Apr-2001: Functions added to the bottom for encrypting/decrypting large ' arrays of data. The entire length of the array is inserted as the first four ' bytes onto the front of the first block of the resultant byte array before ' encryption.
' 3-Apr-2001:添加到底部用于加密/解密大型数据数组的函数。数组的整个长度作为前四'字节插入到生成的字节数组的第一个块的前面,然后进行'加密'。
Are you using those functions, if you are then your encrypting the size bytes too.
您是否正在使用这些函数,如果您正在对大小字节进行加密。
Be assured the .net encryption works well, I'd guess your problem is in the classic solution you've found. If I were in your position I'd start by simplifying things and just encrypt a single block with each method and then expand from there... good luck
请放心。net加密工作得很好,我猜您的问题在您找到的经典解决方案中。如果我处在您的位置,我将从简化开始,用每个方法加密一个块,然后从那里展开……祝你好运
#2
4
Phil Fresle provides a C# version of this code downloadable here: http://www.frez.co.uk/csharp.aspx. The implementation is still different than the classic version as it takes arguments for an initialization vector as well as the block and key size.
Phil Fresle提供了这个代码的c#版本,可以在这里下载:http://www.frez.co.uk/csharp.aspx。该实现仍然与经典版本不同,因为它接受初始化向量以及块和键大小的参数。
You can use this implementation to match the classic version like so:
您可以使用这个实现来匹配经典版本如下:
// Convert the input values to byte[]'s representing ASCII encoding.
// This is what the classic version does
byte[] dataToEncrypt = ASCIIEncoding.ASCII.GetBytes("Ryno");
byte[] password = ASCIIEncoding.ASCII.GetBytes("Saurus");
// Encrypt the data into an array of types
// Notice the block size is 256 bits and the initialization vector is empty.
byte[] results = Rijndael.EncryptData(
dataToEncrypt,
password,
new byte[] { }, // Initialization vector
Rijndael.BlockSize.Block256, // Typically 128 in most implementations
Rijndael.KeySize.Key256,
Rijndael.EncryptionMode.ModeEBC
);
// Convert bytes into a HEX string representation
StringBuilder hex = new StringBuilder(results.Length * 2);
foreach (byte b in results)
hex.AppendFormat("{0:x2}", b);
// FINAL OUTPUT: This matches output of classic ASP Rijndael encryption
string hexEncodedString= hex.ToString();
Most default implementations will use a key size of 128, 192, or 256 bits. A block size at 128 bits is standard. Although some implementations allow block sizes other than 128 bits, changing the block size will just add another item into the mix to cause confusion when trying to get data encrypted in one implementation to properly decrypt in another.
大多数默认实现将使用128、192或256位的密钥。块大小为128位是标准的。虽然有些实现允许使用128位以外的块大小,但是更改块大小只会在混合中添加另一个项,从而在尝试在一个实现中加密数据以在另一个实现中正确解密时造成混乱。
Hopefully this helps.
希望这可以帮助。
Update
Phil's link is no longer available, so I've created a 2 Gists:
Phil的链接不再可用,所以我创建了两个gist:
- ASP / VB Implementation: https://gist.github.com/ryno1234/2fc83faff281babea7f8
- ASP / VB实现:https://gist.github.com/ryno1234/2fc83faff281babea7f8
- C# Implementation with helper class for ASP interop: https://gist.github.com/ryno1234/ea34415643d109974b6f
- c#实现与ASP接口的帮助类:https://gist.github.com/ryno1234/ea34415643d109974b6f
#3
0
Since ASP classic doesn't have native hash functions, you'll probably need to port your MD5 VBScript code to your .NET language, or to use a common cryptography component, due some error on your legacy code.
由于ASP classic没有本地哈希函数,您可能需要将MD5 VBScript代码移植到. net语言,或者使用公共加密组件,因为遗留代码有一些错误。