При расшифровке текста с помощью RSACryptoServiceProvider.Decrypt, Я получаю сообщение об ошибке:
Ошибка при декодировании заполнения OAEP.
Вот мой код:
CspParameters cspParam = new CspParameters();
cspParam = new CspParameters();
cspParam.Flags = CspProviderFlags.UseMachineKeyStore;
clsCertificates cc = new clsCertificates();
string a = "";
cc.OpenStoreIE(ref a);
cc.SetProperties();
X509Certificate2 cert = new X509Certificate2();
cert = cc.x509_2Cert;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspParam);
//to gentrate private and public keys from the certificate
rsa.FromXmlString(cert.PublicKey.Key.ToXmlString(false));
String publicKey = rsa.ToXmlString(false); // gets the public key
String privateKey = rsa.ToXmlString(true); // gets the private key working if paramter is false if true give error key is not valid for use in specified state
Response.Write("<Textarea rows=10 cols=100>PUBLIC: " + publicKey + "</TextArea>");
Response.Write("<Textarea rows=10 cols=100>PRIVATE: " + privateKey + "</Textarea>");
Response.Write("<BR>Encrypting the string "HelloThere" with the public Key:<BR>");
String str = "HelloThere";
RSACryptoServiceProvider RSA2 = new RSACryptoServiceProvider(cspParam);
//---Load the Public key---
RSA2.FromXmlString(publicKey);
//working with the folowing line instead of above but i need the keys of he certificte
//RSA2.ToXmlString(true);
Byte[] EncryptedStrAsByt = RSA2.Encrypt(System.Text.Encoding.Unicode.GetBytes(str), true);
String EncryptedStr = System.Text.Encoding.Unicode.GetString(EncryptedStrAsByt);
Response.Write("<Textarea rows=10 cols=100>Encrypted String: " + EncryptedStr + "</Textarea>");
Response.Write("<BR>Decrypting the Encrypted String with the Private key:<BR>");
RSACryptoServiceProvider RSA3 = new RSACryptoServiceProvider(cspParam);
//---Load the Private key---
RSA3.FromXmlString(privateKey);
//working with the folowing line instead of above but i need the keys of he certificte
//RSA3.ToXmlString(true);
Byte[] DecryptedStrAsByt = RSA3.Decrypt(EncryptedStrAsByt, true );//Error if true then error is error occured while decoding the OAE$P padding and if false then error is bad key i am using windows xp so it should be true.
String DecryptedStr = System.Text.Encoding.Unicode.GetString(DecryptedStrAsByt);
Response.Write("<Textarea rows=10 cols=100>Decrypted String: " + DecryptedStr + "</Textarea>");
Вышеуказанное работает, если я не использую ключи своего цифрового сертификата. но если ключи взяты из цифрового сертификата, я получаю ошибку заполнения OAEP.
Примечание. Этот вопрос является продолжением Ошибка при декодировании заполнения OAEP вопрос
8 ответы
Распространенная ошибка — попытаться расшифровать с помощью открытого ключа.
ответ дан 24 окт ’09, 18:10
Я столкнулся с этой проблемой. UnicodeEncoding.GetBytes не всегда противоположен UnicodeEncoding.GetString.
byte[] a = new byte[32];
RandomNumberGenerator gen = new RNGCryptoServiceProvider();
gen.GetBytes(a);
UnicodeEncoding byteConverter = new UnicodeEncoding();
byte[] b = byteConverter.GetBytes(byteConverter.GetString(a));
//byte array 'a' and byte array 'b' will not always contain the same elements.
Вот почему RSACryptoServiceProvider.Decrypt терпит неудачу. Многие примеры шифрования / дешифрования в Интернете используют кодировку Unicode. Не используйте кодировку Unicode. Использовать Convert.FromBase64String и Convert.ToBase64String .
ответ дан 19 окт ’11, 02:10
Эта ошибка обычно указывает на то, что вы используете открытый ключ для расшифровки, тогда как вы должны использовать закрытый ключ для расшифровки. Попробуйте.
Создан 06 фев.
В моем случае ошибка была вызвана неправильными настройками заполнения.
Error: RSA decrypt: error:0407A079:rsa routines:RSA_padding_check_PKCS1_OAEP:oaep decoding error
У меня было openssl_public_encrypt() с OPENSSL_PKCS1_PADDING как значение по умолчанию в PHP и keypair.decrypt() со значением по умолчанию RSA_PKCS1_OAEP_PADDING in узел-rsa.
Так что не забудьте проверить и эти параметры.
ответ дан 13 авг.
К вашему сведению, вы все еще можете (en / de) шифровать в правильной последовательности ключей (encr: pub key, decr: priv key) — то есть все еще можете получить эту ошибку, расшифровывая закрытым ключом — это просто может быть неправильно закрытый ключ (то есть из другой пары сертификат / ключ), а не тот, который связан с ключом публикации, с помощью которого вы зашифровали изначально. Если вы отключите заполнение OAEP и получите исключение «неверные данные», это еще один признак.
Создан 10 июн.
Шифрование RSA может привести к нечитаемому символу, убедитесь, что строка не обрезана из-за специального символа, указывающего конец чего-либо во время записи / чтения результата шифрования; например, вы не должны использовать strlen, потому что он остановится, когда встретит ‘ 0’ в строке.
ответ дан 26 мая ’14, 03:05
Еще одна вещь, которую нужно проверить: это выдавало мне эту ошибку при операции дешифрования в результате того, что я забыл передать открытый ключ в RSACryptoServiceProvider для операции шифрования.
ответ дан 24 апр.
У нас возникла эта проблема, когда мы использовали неправильный ключ для расшифровки.
Создан 27 янв.
Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками
c#
encryption
rsa
digital-signature
rsacryptoserviceprovider
or задайте свой вопрос.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
void EncryptFile(string inputFile, string outputFile) { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); var rsaOpenKey = RSA.ExportParameters(false);//экспорт открытого ключа rsa.ImportParameters(rsaOpenKey); using (var fstreamIn = new FileStream(inputFile, FileMode.Open, FileAccess.Read)) using (var fstreamOut = new FileStream(outputFile, FileMode.Create, FileAccess.Write)) { byte[] buf = new byte[64]; for (; ; ) { int bytesRead = fstreamIn.Read(buf, 0, buf.Length); if (bytesRead == 0) break; byte[] encrypted = bytesRead == buf.Length ? rsa.Encrypt(buf, true) : rsa.Encrypt(buf.Take(bytesRead).ToArray(), true); fstreamOut.Write(encrypted, 0, encrypted.Length); } } } } void DecryptFile(string inputFile, string outputFile) { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); var rsaPrivateKey = RSA.ExportParameters(true);//экспорт закрытого ключа rsa.ImportParameters(rsaPrivateKey); using (var fstreamIn = new FileStream(inputFile, FileMode.Open, FileAccess.Read)) using (var fstreamOut = new FileStream(outputFile, FileMode.Create, FileAccess.Write)) { byte[] buf = new byte[128]; for (; ; ) { int bytesRead = fstreamIn.Read(buf, 0, buf.Length); if (bytesRead == 0) break; byte[] decrypted = rsa.Decrypt(buf, true); fstreamOut.Write(decrypted, 0, decrypted.Length); } } } } private void Button1_Click(object sender, EventArgs e) { EncryptFile(Environment.CurrentDirectory+"in.txt",Environment.CurrentDirectory+"out.txt"); } private void Button2_Click(object sender, EventArgs e) { DecryptFile(Environment.CurrentDirectory + "out.txt", Environment.CurrentDirectory + "in1.txt"); } } |
- Remove From My Forums
-
Question
-
User1120627064 posted
Hi,
I am half th way of my problem,,. Please Help
I have succesfuly encrypted the text using public key of digital signatures but while decrypting it. i am getting error
Error occurred while decoding OAEP padding
my piece of code
#region
Test Encryption
public void a()
{
using (var rsa = new RSACryptoServiceProvider())
{
// This String consists only Public Key Information
String publicKeyOnly = rsa.ToXmlString(false);
// This String consists both Private/Public Key information
String publicPrivate = rsa.ToXmlString(true);
}
}
//encrypt
public byte[] b(String publicKeyOnly)
{
String s = «<RSAKeyValue><Modulus>vi74tqVrIHSyFELPThmQHUmkZsPx+baueW1reayVWzUe1nT0mZCCqPOcCYKT25E5TLpAh/bMQReLGIvokK+EzzFPqT2Ka0oK0LgPgO2LGZECR4PHdW/UH+bSwWaxN4rikEQGEr0M7rVv5wBFxhcZ/EFv40im+MVIkiM7W2P8PTM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>»;
publicKeyOnly = s;
byte[] encryptedData;
using (var rsaPublicOnly = new RSACryptoServiceProvider())
{
rsaPublicOnly.FromXmlString(publicKeyOnly);
encryptedData = rsaPublicOnly.Encrypt(
Encoding.UTF8.GetBytes(«This String is to be Secured.»), true);
}
return encryptedData;
}
//Decrypt
public String c( byte[] encryptedData)
{
String decryptedPassword ;
using (var rsaPublicPrivate = new RSACryptoServiceProvider())
{
RSACryptoServiceProvider.UseMachineKeyStore = true;
// Providing Private key information to RSA Object
rsaPublicPrivate.FromXmlString(_PrivateKeyXML);
// Decrypting the encrypted data by using RSA object «rsaPublicPrivate»
decryptedPassword = rsaPublicPrivate.Decrypt(encryptedData,
true).ToString();
}
return decryptedPassword;
}
#endregion
- Remove From My Forums
-
Question
-
User1120627064 posted
Hi,
I am half th way of my problem,,. Please Help
I have succesfuly encrypted the text using public key of digital signatures but while decrypting it. i am getting error
Error occurred while decoding OAEP padding
my piece of code
#region
Test Encryption
public void a()
{
using (var rsa = new RSACryptoServiceProvider())
{
// This String consists only Public Key Information
String publicKeyOnly = rsa.ToXmlString(false);
// This String consists both Private/Public Key information
String publicPrivate = rsa.ToXmlString(true);
}
}
//encrypt
public byte[] b(String publicKeyOnly)
{
String s = «<RSAKeyValue><Modulus>vi74tqVrIHSyFELPThmQHUmkZsPx+baueW1reayVWzUe1nT0mZCCqPOcCYKT25E5TLpAh/bMQReLGIvokK+EzzFPqT2Ka0oK0LgPgO2LGZECR4PHdW/UH+bSwWaxN4rikEQGEr0M7rVv5wBFxhcZ/EFv40im+MVIkiM7W2P8PTM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>»;
publicKeyOnly = s;
byte[] encryptedData;
using (var rsaPublicOnly = new RSACryptoServiceProvider())
{
rsaPublicOnly.FromXmlString(publicKeyOnly);
encryptedData = rsaPublicOnly.Encrypt(
Encoding.UTF8.GetBytes(«This String is to be Secured.»), true);
}
return encryptedData;
}
//Decrypt
public String c( byte[] encryptedData)
{
String decryptedPassword ;
using (var rsaPublicPrivate = new RSACryptoServiceProvider())
{
RSACryptoServiceProvider.UseMachineKeyStore = true;
// Providing Private key information to RSA Object
rsaPublicPrivate.FromXmlString(_PrivateKeyXML);
// Decrypting the encrypted data by using RSA object «rsaPublicPrivate»
decryptedPassword = rsaPublicPrivate.Decrypt(encryptedData,
true).ToString();
}
return decryptedPassword;
}
#endregion
- Remove From My Forums
-
Вопрос
-
Добрый день, коллеги!
Пытаюсь настроить работу WAC (2009) WinRM for HTTPS, провел подготовительные работы на удаленном ПК согласно
статье. Но при попытке подключиться выходит следующая ошибка и не могу понять почему:
Connecting to remote server srv01.contoso.local failed with the following error message : The server certificate on the destination computer (srv1.contoso.local:5986) has the following errors: The SSL certificate could not be checked for revocation. The server used to check for revocation might be unreachable. For more information, see the about_Remote_Troubleshooting Help topic.
Проверил CRL доступны, в Enterprise PKI тоже все ОК, в чем проблема не могу понять, есть у кого соображения по этому поводу?
Даже сам на себя через WAC не получается зайти :-(, когда-то пробовал данный функционал все без проблем работало, может глюк новой версии?
Ответы
-
Действительно как только я настроил OCSP и выпустил новый сертификат все заработало.
-
Помечено в качестве ответа
30 декабря 2020 г. 13:10
-
Помечено в качестве ответа
В принципе проблема решена, но так как считывание происходит поблочно, размер блока сильно влияет на скорость. С шифрованием все гуд. Метод для шифрования:
public bool Encrypt_RSA_File(string inputFile, string outFile, string fileext, int keySize, string xmLstring)
{
try
{
var rsa = new RSACryptoServiceProvider(keySize);
rsa.FromXmlString(xmLstring);
using (var fstreamIn = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
using (var fstreamOut = new FileStream(outFile, FileMode.Append, FileAccess.Write))
using (var bw = new BinaryWriter(fstreamOut))
{
byte[] extbytes = Encoding.Unicode.GetBytes(fileext);
byte[] extencrypted = rsa.Encrypt(extbytes, true);
bw.Write(extencrypted, 0, extencrypted.Length);
byte[] buf = new byte[64];
byte[] temp = File.ReadAllBytes(inputFile);
_currentMaxProg = temp.Length;
for (; ; )
{
if (_cancelled)
{
_currentProg = 0;
_currentMaxProg = 0;
return false;
}
int bytesRead = fstreamIn.Read(buf, 0, buf.Length);
_currentProg += bytesRead;
if (bytesRead == 0) break;
byte[] encrypted = bytesRead == buf.Length ? rsa.Encrypt(buf, true) : rsa.Encrypt(buf.Take(bytesRead).ToArray(), true);
fstreamOut.Write(encrypted, 0, encrypted.Length);
if (CurrentProgressChanged != null) CurrentProgressChanged(_currentProg);
Application.DoEvents();
}
_currentProg = 0;
_currentMaxProg = 0;
if (CurrentProgressChanged != null) CurrentProgressChanged(_currentProg);
}
return true;
}
catch (Exception ex) { MessageBox.Show(ex.Message); return false; }
}
бинарным писателем пишем в выходной файл расширение исходного файла в зашифрованном виде — работает.
сам метод вызывается так:
if (_crypter.Encrypt_RSA_File(path, path.Replace(fileext, ".crypt"), fileext, _view.RsAstrength, _xmLstring))
{
_view.LogContent += _logger.WriteToLog("шифрование файла " + path + " завершилось успешно");
_view.LogContent += _logger.WriteToLog(string.Concat("файл сохранен как ", path.Replace(fileext, ".crypt")));
}
else
{
_view.LogContent += _logger.WriteToLog("операция прервана. Файл" + path + " не обработан.");
_manager.Delete((T)Convert.ChangeType(path.Replace(fileext, ".crypt"), typeof(T)));
return;
}
Теперь непосредственно о том, что под вопросом. Следующим способом
string fileext = _crypter.DecryptRsaExtension(path, _view.RsAstrength, _xmLstring);
if (_crypter.Decrypt_RSA_File(path, path.Replace(".crypt", fileext), _view.RsAstrength, _xmLstring))
{
_view.LogContent += _logger.WriteToLog("расшифровка файла " + path + " завершилась успешно");
_view.LogContent += _logger.WriteToLog(string.Concat("файл сохранен как ", path.Replace(".crypt", "")));
}
else
{
_view.LogContent += _logger.WriteToLog("операция прервана. Файл" + path + " не обработан.");
_manager.Delete((T)Convert.ChangeType(path.Replace(".crypt", ""), typeof(T)));
return;
}
сначала выдираем и расшифровываем расширение файла и передаем его как один из параметров для расшифровки основной части зашифрованного файла. Расширение выдирается так:
public string DecryptRsaExtension(string path, int keySize, string xmLstring)
{
var fstreamIn = new FileStream(path, FileMode.Open, FileAccess.Read);
byte[] buf = new byte[RsaEncFileExtSize(keySize)];
var rsa = new RSACryptoServiceProvider(keySize);
rsa.FromXmlString(xmLstring);
fstreamIn.Read(buf, 0, buf.Length);
byte[] decrypted = rsa.Decrypt(buf, true);
var ext = Encoding.Unicode.GetString(decrypted);
return ext;
}
RsaEncFileExtSize(keySize) нужен для того, чтобы на основе размера ключа с которым шифровали файл определить количество байт, которые нам нужны для получения расширения. Работает очень просто:
private int RsaEncFileExtSize(int keySize)
{
int result = 0;
switch (keySize)
{
case 1024: result = 128; break;
case 2048: result = 256; break;
case 3072: result = 384; break;
case 4096: result = 512; break;
case 5120: result = 640; break;
}
return result;
}
Далее сам метод расшифровки:
public bool Decrypt_RSA_File(string encryptedFile, string decryptedFile, int keySize, string xmLstring)
{
try
{
var rsa = new RSACryptoServiceProvider(keySize);
rsa.FromXmlString(xmLstring);
using (var fstreamIn = new FileStream(encryptedFile, FileMode.Open, FileAccess.Read))
using (var fstreamOut = new FileStream(decryptedFile, FileMode.Create, FileAccess.Write))
{
int ext = RsaEncFileExtSize(keySize);
byte[] buf = new byte[384];
byte[] temp = File.ReadAllBytes(encryptedFile);
_currentMaxProg = temp.Length;
for (; ; )
{
if (_cancelled)
{
_currentProg = 0;
_currentMaxProg = 0;
return false;
}
var bytesRead = fstreamIn.Read(buf, 0, buf.Length);
_currentProg += bytesRead;
if (bytesRead == 0) break;
if (_currentProg > ext)
{
byte[] decrypted = rsa.Decrypt(buf, true);
fstreamOut.Write(decrypted, 0, decrypted.Length);
if (CurrentProgressChanged != null) CurrentProgressChanged(_currentProg);
Application.DoEvents();
}
}
_currentProg = 0;
_currentMaxProg = 0;
if (CurrentProgressChanged != null) CurrentProgressChanged(_currentProg);
}
return true;
}
catch (Exception ex) { MessageBox.Show(ex.Message); return false; }
}
Если я указываю размер buf = 384, все работает, но оооооочень медленно. Файл, который занимает в исходном и зашифрованном виде 10 с чем-то и 30 с чем-то метров соответственно расшифровывается 10-15 минут. И да, я помню, что вместо 384 надо писать RsaEncFileExtSize(int keySize), но на данный момент тестирую с ключом 3072. Если же пишу 64, 128, 192, 256, выдает ошибку декодирования заполнения OAEP на строке byte[] decrypted = rsa.Decrypt(buf, true);, когда _currentProg > 384. Внимание вопрос: Как можно уменьшить размер считываемого блока, чтобы не было ошибки заполнения? Либо как повысить производительность для buf=384 или RsaEncFileExtSize(intkeySize)?
P.S. просто решил избавиться от зашифрованных файлов с двойным расширением. Если при шифровании расширение записывать в чистом виде(без шифрования), проблема та же.
замена на byte[] buf = new byte[ext]; где ext = RsaEncFileExtSize(keySize); не решает проблемы.
Я написал 3 функции на C ++, используя Crypto ++ для генерации пар ключей, шифрования и дешифрования строки. Сторона Crypto ++:
//Decode public key
RSA::PublicKey pbKeyDecoded;
StringSource ss2(publicKey, true, new Base64Decoder);
pbKeyDecoded.BERDecode(ss2);
Integer m = Integer((const byte*)plaintext.data(), plaintext.size());
Integer crypted = pbKeyDecoded.ApplyFunction(m);
...
Я создаю ключ, кодирую его DER, а затем кодирую его в Base64. После этого я шифрую открытый текст с помощью открытого ключа и сохраняю как закрытый ключ, так и шифр как строки в кодировке base64 в двух отдельных файлах.
Теперь на C #. Я читаю строку base64, декодирую их и загружаю через AsnParser, который, кажется, загружается просто отлично. Тогда я звоню Decrypt, Сторона C #:
AsnKeyParser keyParser = new AsnKeyParser("rsa-public.der");
RSAParameters publicKey = keyParser.ParseRSAPublicKey();
CspParameters csp = new CspParameters;
csp.KeyContainerName = "RSA Test (OK to Delete)";
csp.ProviderType = PROV_RSA_FULL; // 1
csp.KeyNumber = AT_KEYEXCHANGE; // 1
RSACryptoServiceProvider rsp = new RSACryptoServiceProvider(csp);
rsp.PersistKeyInCsp = false;
rsp.ImportParameters(privateKey);
//Causes exception here..
var data = rsp.Decrypt(cipherArr, true);
...
Но я получаю ошибку исключения, когда пытаюсь расшифровать fOAEP = true: CryptographicException: произошла ошибка при декодировании заполнения OAEP. Если я пройду fOAEP = false тогда я получаю CryptographicException: параметр неверен.
Почему я получаю исключение в C # при попытке расшифровать зашифрованный текст Crypto ++?
0
Решение
… Я получаю сообщение об ошибке исключения при попытке расшифровать его: CryptographicException: произошла ошибка при декодировании заполнения OAEP. Это если я передаю true для bool fOAEP, если я передаю false, я получаю CryptographicException: параметр неверен.
У вас та же проблема, что и Зашифровать и расшифровать сообщение, используя необработанный алгоритм RSA в Crypto ++? а также Как синхронизировать Crypto ++ RSA с провайдером криптографических услуг C # RSA? Это должен быть наш месяц для схем «Raw RSA» …
На стороне уравнения Crypto ++, вы выполняете сырой RSA. Вы просто применяете функцию пересылки, которая является возведением в степень, и вы не форматируете сообщение:
//Decode public key
RSA::PublicKey pbKeyDecoded;
StringSource ss2(publicKey, true, new Base64Decoder);
pbKeyDecoded.BERDecode(ss2);
Integer m = Integer((const byte*)plaintext.data(), plaintext.size());
Integer crypted = pbKeyDecoded.ApplyFunction(m);
...
На стороне C # вещей, вы выполняете расшифровку RSA используя PKCS # 1 с заполнением PKCS # 1.5 или OAEP:
RSACryptoServiceProvider rsp = new RSACryptoServiceProvider(csp);
rsp.PersistKeyInCsp = false;
rsp.ImportParameters(privateKey);
//Causes exception here..
var data = rsp.Decrypt(cipherArr, true);
Мне не ясно, может ли версия C # вашего кода выполнять заполнение OAEP, потому что для этого требуется определенная версия CLR. У вас может быть только доступное дополнение PKCS.
Я считаю, что у вас есть два варианта. Во-первых, вы можете использовать стандартный метод шифрования RSA в Crypto ++. Вики Crypto ++ перечисляет их в RSA Криптография а также Схемы шифрования RSA:
typedef RSAES<PKCS1v15>::Decryptor RSAES_PKCS1v15_Decryptor;
typedef RSAES<PKCS1v15>::Encryptor RSAES_PKCS1v15_Encryptor;
typedef RSAES<OAEP<SHA> >::Decryptor RSAES_OAEP_SHA_Decryptor;
typedef RSAES<OAEP<SHA> >::Encryptor RSAES_OAEP_SHA_Encryptor;
Во-вторых, вам нужно выполнить Raw RSA в C #. Чтобы выполнить Raw RSA в C #, вам нужно получить класс BigInteger и применить обратную функцию вручную.
Я бы посоветовал вам использовать RSA Encryption с заполнением OAEP. Если OAEP недоступен, то вторым вариантом будет заполнение PKCS. Наконец, если все, что у вас есть, это Raw RSA, то я бы искал другую систему шифрования, потому что Raw RSA настолько небезопасен.
1
Другие решения
Других решений пока нет …