0

I am migrating a webservice/database written in Microsoft .net framework to ruby. I am stuck at the password encryption part because I can't replicate the encryption on ruby side. Here's the code that generates an encrypted password in .net:

    private static String GetSecret()
    {
        string nexus = ConfigurationManager.AppSettings["Nexus"];
        System.Security.SecureString plain = ProtectedSettings.DecryptString(nexus);
        return ProtectedSettings.ToInsecureString(plain);
    }

    private static String EncryptPassword(string password)
    {
        return SymmetricEncryption.Encrypt<AesManaged>(password, GetSecret());
    }

I got the string named nexusand in ruby, using the aes gem, I did:

AES.encrypt(a_password, key)

but the generated hash doesn't match the one in .net. What am I missing? thanks

Here's the Encrypt function:

public static string Encrypt<T>(string value, string password, string salt = "4AFB7A1414E4486FAB51A42F5D0D6E7B")
             where T : SymmetricAlgorithm, new()
        {
            DeriveBytes rgb = new Rfc2898DeriveBytes(password, Encoding.Unicode.GetBytes(salt));

            SymmetricAlgorithm algorithm = new T();

            byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
            byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);

            ICryptoTransform transform = algorithm.CreateEncryptor(rgbKey, rgbIV);

            using (MemoryStream buffer = new MemoryStream())
            {
                using (CryptoStream stream = new CryptoStream(buffer, transform, CryptoStreamMode.Write))
                {
                    using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
                    {
                        writer.Write(value);
                    }
                }

                return Convert.ToBase64String(buffer.ToArray());
            }
        }

Ok so I have tried converting this code to ruby, but with no luck:

p = PBKDF2.new(:password => pass, :salt => salt, :iterations => 1000)  
iv = p.hash_function.digest[0..15]
key = p.hash_function.digest[0..31]
aes = OpenSSL::Cipher::Cipher.new("AES-128-CBC")
aes.encrypt
aes.key = key
aes.iv = iv 
aes.update("1123581321") + aes.final
0xSina
  • 20,973
  • 34
  • 136
  • 253
  • You have not even touched the part for PBKDF2 (`Rfc2898DeriveBytes`) it seems. Maybe read up on cryptography first. Then *start* with the key derivation part. – Maarten Bodewes Jun 11 '13 at 22:48
  • @owlstead I did that but with no luck. Can you please take a look at my attempt at this in ruby? – 0xSina Jun 12 '13 at 01:05
  • If your key *is* 32 bytes then I presume you have to use AES-256. The 256 in AES is the key size, so `256 / 8 = 32`... First compare the derived key values (in hex), then go on with the AES part... – Maarten Bodewes Jun 12 '13 at 20:15

1 Answers1

3

There are several things which could be going on.

  1. You could be using a different cipher block padding scheme
  2. You could be using a different key size
  3. Your initialisation vector for the AES engine could be different.
  4. Your key could be incorrect
  5. Your plaintext could be in a different character set

You need to establish the settings used during encryption in your .Net environment, then you need to replicate these in your ruby environment.

Getting incorrect decryption value using AesCryptoServiceProvider touches on the use of the initialization vector (IV) in .net

http://developer.mintrus.com/2011/08/aes-encryption-in-ruby-on-rails/ gives a brief tutorial on AES in ruby (specifically in rails, but it is applicable to your situation

Community
  • 1
  • 1
mcfinnigan
  • 11,442
  • 35
  • 28
  • Thanks for the input. The IV is generate by 'ICryptoTransform' which I have no idea what it is. I posted the details in my original question, can you please take a look? – 0xSina Jun 11 '13 at 21:09
  • @0xSina your IV is in your encrypt block : `byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);` - establish what the byte values are in this array and use them in your ruby encrypt function's IV – mcfinnigan Jun 11 '13 at 21:48
  • I did that, but with no luck. Can you please take a look at my attempt at this in ruby? – 0xSina Jun 12 '13 at 01:06
  • @Trip nop. It's been a while, but luckily the password weren't hashed, just encrypted. So I decrypted them using .NET framework, and then hashed them using Ruby and then entered them into my db. – 0xSina Mar 31 '14 at 19:18
  • @0xSina So your Ruby app used a .net framework to decrypt the AES? I think I'm having a similar issue where the AES strings are being encrypted in Microsoft, and for some reason, Mac OS X or Ruby doesn't understand the same binary/variables/etc. – Trip Apr 01 '14 at 10:42
  • @Trip no. The app was written in .NET framework. I rewrote the app in Rails, an migrated the DB over from MSSQL to MySQL. The only issue was the passwords were encrypted using some .NET library and I couldn't replicate it in Ruby. So using the same .NET library that encrypted the, i decrypted them, and rehashed them using Ruby and fed them into my new DB. – 0xSina Apr 01 '14 at 21:12