Почему при попытке сделать Decrypt строки с помощью public key я получаю исключение "Key does not exist."
var storage = new X509Store(StoreName.My, StoreLocation.CurrentUser);
storage.Open(OpenFlags.ReadOnly);
var cerificates = storage.Certificates.Find(X509FindType.FindBySubjectName, "Personal Certificate", true);
var signCert = cerificates[0];
var publicKey = (RSACryptoServiceProvider)signCert.PublicKey.Key;
var privateKey = (RSACryptoServiceProvider)signCert.PrivateKey;
var test = "это тест";
var data = Encoding.UTF8.GetBytes(test);
var clipperData = privateKey.Encrypt(data, false);
data = publicKey.Decrypt(clipperData, false);
test = Encoding.UTF8.GetString(data);
Здравствуйте, Norex, Вы писали:
N> var clipperData = privateKey.Encrypt(data, false); N> data = publicKey.Decrypt(clipperData, false); N> test = Encoding.UTF8.GetString(data);
Вообще-то надо наоборот : publicKey.Encrypt и privateKey.Decrypt. Какой смысл шифровать приватным, если если расшифровать публичным ключом может кто угодно? Ну и приватный ключ для данного сертификата должен существовать.
Здравствуйте, Jolly Roger, Вы писали: JR>Вообще-то надо наоборот : publicKey.Encrypt и privateKey.Decrypt. Какой смысл шифровать приватным, если если расшифровать публичным ключом может кто угодно? Ну и приватный ключ для данного сертификата должен существовать.
Дак в том-то и дело, что мне и нужно что бы зашифровать мог только один ключ.
Но, приватный ключ способен на обе операции. Фактически мне было бы достаточно подписать строку, что бы удалённая сторона могла бы проверить, что строка не изменилась. Осложняется это тем, что удалённая сторона — это НЕ .net приложение.
Здравствуйте, Norex, Вы писали:
N>Дак в том-то и дело, что мне и нужно что бы зашифровать мог только один ключ. N>Но, приватный ключ способен на обе операции.
Поддерживать-то он поддерживает... Вопрос в том, что поддерживает провайдер, а с чем лесом посылает. У меня, например, попытка дешифрации открытым ключом возвращает "bad key".
N>Фактически мне было бы достаточно подписать строку, что бы удалённая сторона могла бы проверить, что строка не изменилась. Осложняется это тем, что удалённая сторона — это НЕ .net приложение.
Ну так и подписывайте
var clipperData = privateKey.SignData(data, new SHA1CryptoServiceProvider());
if (! publicKey.VerifyData(data, new SHA1CryptoServiceProvider(), clipperData)) throw ...
А вообще лучше использовать сеансовый ключ, как в SSL/TLS. Клиент сгенерил симметричный ключ, зашифровал публичным из сертификата сервера и передал серверу. Тот расшифровал и далее в течении сеанса используется этот сеансовый ключ. При желании можно ограничить по времени, меняя симметричный ключ несколько раз за сеанс. По крайней мере, симметричные алгоритмы работают куда быстрее асимметричных.
Здравствуйте, Norex, Вы писали:
N>Не могу я подписывать в простом варианте. N>У меня клиент — не .NET приложение.
Если Вам нужен контроль подлинности данных, то цифровая подпись — это то, что Вам нужно. Это стандарт, безотнасительно любых фреймвоков и платформ. Методы SignData и SignHash переадресуют вызов соответствующему провайдеру — ровно так-же, как это делается и в нативном коде. Что такое цифровая подпись? Это хэш Ваших данных, вычисленный указанным Вами алгоритмом и зашифрованный приватным ключом. Средства для этого есть практически на любой платформе. А если где нет, то там уже ничего не поможет.
Ну а то, что Вы изначально задумали — это, пардон, велосипед даже не с квадраьными колёсами, а вообще без колёс и руля