Невозможно раскодировать строки Login/Password
От: AlexGin Беларусь  
Дата: 30.01.17 07:57
Оценка: :)))
Добрый день, уважаемые коллеги!

В процессе разработок у меня возникла необходимость хранения закодированных строк Login/Password.
Я это сделал в специальном текстовом файле, используя материал — описанный в единственном ответе здесь:
http://stackoverflow.com/questions/32639113/how-to-store-information-like-passwords-encrypted-but-not-in-hash

Далее возникла проблема: на моём компьютере вызов раскодировки строки:
 public string DecryptPassword(string sEncryptedPassword)
        {
            var encrypted_data = Convert.FromBase64String(sEncryptedPassword);
            var data = ProtectedData.Unprotect(encrypted_data, null, DataProtectionScope.CurrentUser); // !!! ПРОБЛЕМА ЗДЕСЬ !!!
            return Encoding.UTF8.GetString(data);
        }

проходит нормально.

Но на компьютерах моих товарищей — вызов:
var data = ProtectedData.Unprotect(encrypted_data, null, DataProtectionScope.CurrentUser); приводит к исключению:

Key not valid for use in specified state.

При этом, данные в строке sEncryptedPassword — одинаковые.
Почему у меня они идут как валидные, а на других компах — как НЕвалидные?
Куда копать?
Что делать?

Заранее благодарен, за любые советы!
Отредактировано 30.01.2017 18:35 AndrewVK . Предыдущая версия . Еще …
Отредактировано 30.01.2017 9:50 AlexGin . Предыдущая версия .
protecteddata
Re: Невозможно раскодировать строки Login/Password
От: Sinix  
Дата: 30.01.17 08:40
Оценка: +1
Здравствуйте, AlexGin, Вы писали:

AG>Почему у меня они идут как валидные, а на других компах — как НЕвалидные?

DataProtectionScope:

CurrentUser
The protected data is associated with the current user. Only threads running under the current user context can unprotect the data.
LocalMachine
The protected data is associated with the machine context. Any process running on the computer can unprotect data. This enumeration value is usually used in server-specific applications that run on a server where untrusted users are not allowed access.


Global, внезапно, нет

AG>Куда копать?

AG>Что делать?
Определиться с задачей, изучить, как оно решается, подобрать подходящее решение.
Re[2]: Невозможно раскодировать строки Login/Password
От: AlexGin Беларусь  
Дата: 30.01.17 09:39
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Global, внезапно, нет

    public string EncryptPassword(string sPassword)
        {
           var data = Encoding.UTF8.GetBytes(sPassword);
           var encrypted_data = ProtectedData.Protect(data, null, DataProtectionScope.CurrentUser);
           string sOut = Convert.ToBase64String(encrypted_data);
           // return Convert.ToBase64String(encrypted_data);
           return sOut; // Use ONLY this variant od return !!!
        }

        public string DecryptPassword(string sEncryptedPassword)
        {
            var encrypted_data = Convert.FromBase64String(sEncryptedPassword); 
            var data = ProtectedData.Unprotect(encrypted_data, null, DataProtectionScope.CurrentUser); // !!! Exception происходит здесь !!!
            return Encoding.UTF8.GetString(data);
        }

Внезапно — нет!
Всюду применяются опции: DataProtectionScope.CurrentUser

AG>>Куда копать?

AG>>Что делать?
S>Определиться с задачей, изучить, как оно решается, подобрать подходящее решение.
Здесь задача простая: хранить пару Login/Password в закодированном виде (в специальном файле).
Имеется два вида файлов: общий, где хранятся все пары (аккаунты для всех юзеров); индивидуальный — аккаунты только одного.
Запись в этот файл — единожды (например — добавили в систему нового юзера с его аккаунтом), чтение — многократно, при входе (авторизации) каждого.

Возможно ли, что данная проблема из-за того, что:
Первоначальная генерация этих двух файлов с парами Login/Password — имела место ТОЛЬКО НА МОЁМ компьютере?
У товарищей — я даю только чтение — которое вызывает exception:

Key not valid for use in specified state

Отредактировано 30.01.2017 9:47 AlexGin . Предыдущая версия . Еще …
Отредактировано 30.01.2017 9:41 AlexGin . Предыдущая версия .
Re[3]: Невозможно раскодировать строки Login/Password
От: Sinix  
Дата: 30.01.17 10:10
Оценка: 7 (3)
Здравствуйте, AlexGin, Вы писали:


AG>Всюду применяются опции: DataProtectionScope.CurrentUser

    public static byte [] Protect( byte [] data )
    {
        // Encrypt the data using DataProtectionScope.CurrentUser. The result can be decrypted
        //  only by the same current user.
        return ProtectedData.Protect( data, s_aditionalEntropy, DataProtectionScope.CurrentUser );
    }

(с).

Дальше см вот это

DPAPI and Roaming Profiles

DPAPI works as expected with roaming profiles for users and computers that are joined to an Active Directory directory service domain. DPAPI data that is stored in the profile acts exactly like any other setting or file that is stored in a roaming profile. Confidential information that the DPAPI helps protect are uploaded to the central profile location during the logoff process and are downloaded from the central profile location when a user logs on.

For DPAPI to work correctly when it uses roaming profiles, the domain user must only be logged on to a single computer in the domain. If the user wants to log on to a different computer that is in the domain, the user must log off the first computer before the user logs on to the second computer. If the user is logged on to multiple computers at the same time, it is likely that DPAPI will not be able to decrypt existing encrypted data correctly.


Т.е. работать будет при условии, что есть AD, работает profile roaming и пользователь не залогинен одновременно на нескольких машинах.


AG>У товарищей — я даю только чтение — которое вызывает exception:

Key not valid for use in specified state

Ну таки да — профиль-то пользователя другой, с чего бы данным читаться?
Два варианта — или городить что-то своё, или хранить в protected data ключ расшифровки данных (и соответственно задавать его на каждой новой машине при установке). По надёжности — не особо лучше, чем plaintext в файле с ограниченными правами.
Re[4]: Невозможно раскодировать строки Login/Password
От: AlexGin Беларусь  
Дата: 30.01.17 10:27
Оценка:
Здравствуйте, Sinix, Вы писали:

AG>>У товарищей — я даю только чтение — которое вызывает exception:

S>

S> Key not valid for use in specified state

S>Ну таки да — профиль-то пользователя другой, с чего бы данным читаться?
S>Два варианта — или городить что-то своё, или хранить в protected data ключ расшифровки данных (и соответственно задавать его на каждой новой машине при установке). По надёжности — не особо лучше, чем plaintext в файле с ограниченными правами.


Посмотрел сюда:
https://support.microsoft.com/ru-ru/help/309408/how-to-troubleshoot-the-data-protection-api-dpapi — спасибо за ссылочку!

Всё понятно
Когда генерирую файл с парой Login/Password на каждом из компов товарищей — всё отлично работает!
В общем-то это именно то, что и требовалось доказать!
Спасибо!
Отредактировано 30.01.2017 10:32 AlexGin . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.