4

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.

I found this Rijndael code to use with classic 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:

        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.

SwDevMan81
  • 45,922
  • 20
  • 140
  • 177
Stief Dirckx
  • 85
  • 1
  • 5
  • We are using the exact same code in a legacy part of our Classic ASP (vbScript) application to encrypt strings... which IMHO is more like obfuscation than encryption. I have took a look at the Classic ASP version, with my limited knowledge in cryptography, I think the code does not use an IV at all. If someone knows if it is possible to use `RijndaelManaged` without an Initialisation Vector (IV) I think it could help a lot. – MaxiWheat Apr 24 '12 at 22:33
  • Why do you want decryptable passwords? Why not simply allow a user to generate a new password of their choice? – Nik Bougalis Feb 08 '13 at 00:28

3 Answers3

5

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.

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.

Hopefully this helps.

Update

Phil's link is no longer available, so I've created a 2 Gists:

Ryan Griffith
  • 1,481
  • 15
  • 37
  • 1
    Using a blank IV defeats the purpose of CBC and is not secure. – SLaks Dec 27 '13 at 15:31
  • Good point. The issue is that the VB Script encryption being used in the OP's question actually uses a blank Initialization Vector. For the sake of simply having a .Net version that is compatible with the VB Script version, a blank IV is required. Thank you for making others aware of the blank IV detail. – Ryan Griffith Dec 27 '13 at 18:07
  • @RyanGriffith, may you please help me with the decrypt method, i have created a new question here http://stackoverflow.com/questions/20801952/converting-vb6-aes-rijndael-block-cipher-to-c-sharp-by-phil-fresle – sawe Dec 30 '13 at 11:38
  • It appears Phil Fresle's implementation link has gone down :(. – cchamberlain Sep 08 '15 at 18:50
  • 1
    Hi @cchamberlain, I've created a Gist which includes Phil's original version along with the interoperability code above. https://gist.github.com/ryno1234/ea34415643d109974b6f – Ryan Griffith Sep 08 '15 at 20:55
  • Thanks @RyanGriffith! I couldn't find it anywhere. Any chance you have the VBScript implementation lieing around? – cchamberlain Sep 08 '15 at 21:00
  • 1
    @cchamberlain, you can find it here: https://gist.github.com/ryno1234/2fc83faff281babea7f8 , good luck! – Ryan Griffith Sep 08 '15 at 21:40
  • 1
    @RyanGriffith - Thanks so much. I had a go at running the C# version in a COM+ component and that appears to be working great so didn't end up needing the classic version but nice to have a fallback anyway (and will probably help future people upgrading 20 year old code). – cchamberlain Sep 09 '15 at 20:38
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.

Rubens Farias
  • 54,126
  • 8
  • 125
  • 158
  • MD5 is no problem, this has been working for years now both for classic asp and ASP.NET. But I want to convert everything to Rijndael encryption to make passwords also decryptable. – Stief Dirckx Nov 05 '09 at 09:26
  • same applies: if those two methods, by different algorithms, results doesn't match, use same algorithm and they will. OR, you'll need to do hard way: validating Phil Fresle's AES Rijndael Block Cipher implementation – Rubens Farias Nov 05 '09 at 09:31
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:

' 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.

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

Patrick
  • 7,599
  • 7
  • 49
  • 71
  • 1
    Thanks Patrick, so the classic asp solution doesn't really stick to the standard encryption method. I'm thinking to develop a dll in .NET that takes care of the encryption and make that dll callable form classic asp. – Stief Dirckx Nov 09 '09 at 08:37
  • I didn't look that closely but it looks like the classic asp just does AES which isn't very useful by itself but the code does what it says on the tin... you could add the block mode yourself perhaps but .net does it all for you... – Patrick Nov 09 '09 at 11:25