Расшифрованный текст из шифрования AES имеет дополнительные пробелы - PullRequest
2 голосов
/ 13 апреля 2011

Я пытаюсь расшифровать пароли, которые были сохранены в базе данных из стандартного SqlMembershipProvider.Чтобы сделать это, я взломал следующее консольное приложение:

    static void Main(string[] args)
    {
        const string encryptedPassword = @"wGZmgyql4prPIr7t1uaxa+RBRJC51qOPBO5ZkSskUtUCY1aBpqNifQGknEfWzky4";
        const string iv = @"Jc0RhfDog8SKvtF9aI+Zmw==";
        var password = Decrypt(encryptedPassword, iv);

        Console.WriteLine(password);
        Console.ReadKey();
    }

    public static string Decrypt(string toDecrypt, string iv)
    {
        var ivBytes = Convert.FromBase64String(iv);
        const string decryptKey = "DECRYPTION_KEY_HERE";
        var keyArray = StringToByteArray(decryptKey);
        var toEncryptArray = Convert.FromBase64String(toDecrypt);
        var rDel = new AesCryptoServiceProvider() { Key = keyArray, IV = ivBytes};
        var cTransform = rDel.CreateDecryptor();
        var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        return Encoding.UTF8.GetString(resultArray);
    }

    public static byte[] StringToByteArray(String hex)
    {
        var numberChars = hex.Length;
        var bytes = new byte[numberChars / 2];
        for (var i = 0; i < numberChars; i += 2)
            bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
        return bytes;
    }

Это действительно расшифровывает текст, однако вместо получающегося текста, похожего на «Password1», это «\ 0 \ 0 \ 0».\ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0P \ 0a \ 0s \ 0s \ 0w \ 0o \ 0r \ 0d \ 01 \ 0 ", который пишет в консолькак куча пробелов, то "P assword 1".Есть идеи, что я делаю не так?

1 Ответ

2 голосов
/ 13 апреля 2011

Я подозреваю, что часть проблемы может заключаться в том, что перед шифрованием исходный пароль был закодирован как UTF-16, а вы расшифровываете его как UTF-8. Попробуйте изменить последнюю строку вашего Decrypt метода:

return Encoding.Unicode.GetString(resultArray);

Это не объясняет всех этих ложных ведущих нулей. Очень странно ...

EDIT ...

На самом деле, я, кажется, помню, что SqlMembershipProvider перед шифрованием ставит префикс байтов пароля 16-байтовой солью, и в этом случае вам, вероятно, удастся сойти с рук что-то вроде этого:

return Encoding.Unicode.GetString(resultArray, 16, resultArray.Length - 16);

Но это все же не объясняет, почему все эти 16 байтов являются нулями, а не набором случайных значений ...

...