«Плохие данные» CryptographicException - PullRequest
9 голосов
/ 12 марта 2012

Во-первых, я написал код ниже только для академических целей. Причина, по которой я это говорю, заключается в том, что я не помещаю это в производственную среду, и поэтому «обхожу» некоторые накладные расходы, которые мне потребовались бы, если бы я был, мне просто нужно иметь возможность шифровать / дешифровать строку, используя код ниже. Я смог сделать это несколько раз, но по какой-то причине я начал получать «CryptographicException Bad Data» и не уверен, что может быть причиной проблемы.

   private string RSAEncrypt(string value)
    {
        byte[] encryptedData = Encoding.Unicode.GetBytes(value);

        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = _rsaContainerName;
        using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams))
        {
            encryptedData = RSA.Encrypt(encryptedData, false);
            return Convert.ToBase64String(encryptedData);

        }

    }



    private string RSADecrypt(string value)
    {

        byte[] encryptedData = Encoding.Unicode.GetBytes(value);

        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = _rsaContainerName;
        using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams))
        { 
            encryptedData = RSA.Decrypt(encryptedData,false);
            return Convert.ToBase64String(encryptedData);

        }
    }

Это исключение возникает только при вызове RSADecrypt.

Есть идеи? Я где-то читал, что это может быть связано с ожидаемым размером encryptedData, который передается в RSA.Decrypt.

Спасибо }

Ответы [ 4 ]

16 голосов
/ 12 марта 2012
  • Преобразование открытого текста вперед и назад с использованием строкового кодирования (т. Е. Encoding.Unicode).

  • Преобразование зашифрованных данных назад и вперед с использованием Base-64(т.е. Convert.[To/From]Base64String);

Как это:

private string RSAEncrypt(string value)
{
    byte[] plaintext = Encoding.Unicode.GetBytes(value);

    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = _rsaContainerName;
    using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams))
    {
        byte[] encryptedData = RSA.Encrypt(plaintext, false);
        return Convert.ToBase64String(encryptedData);
    }
}

private string RSADecrypt(string value)
{
    byte[] encryptedData = Convert.FromBase64String(value);

    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = _rsaContainerName;
    using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams))
    { 
        byte[] decryptedData = RSA.Decrypt(encryptedData,false);
        return Encoding.Unicode.GetString(decryptedData);
    }
}
6 голосов
/ 12 марта 2012

http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx

Не использовать зашифрованный текст с помощью строкового кодирования

Одна распространенная ошибка, которую допускают люди при использовании управляемого шифрования классы в том, что они пытаются сохранить результат шифрования операция в строке с использованием одного из классов кодирования. Тот кажется, имеет смысл правильно? В конце концов, Encoding.ToString () принимает byte [] и преобразует его в строку, которая в точности соответствует ищу.

...

Вместо этого, если вы хотите преобразовать зашифрованный текст в строку, используйте Кодировка Base64.

...

В результате получается код, который работает каждый раз, поскольку кодировка base 64 гарантированно может точно представлять любую последовательность входных байтов.

Здесь есть хороший, правильный пример: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx

1 голос
/ 12 марта 2012

RSA не предназначен для шифрования больших объектов.Вы получите исключения, если вы превысите предел заполнения.Фактическое ограничение основано на самом заполнении (использование false означает, что вы используете заполнение old PKCS # 1 v1.5) и длину вашего открытого ключа (2048 бит).

Правильный способ использования RSA с крупным объектом - это шифрование большого объекта симметричным ключом (например, 256-битным AES секретным ключом) и шифрование этого маленького ключа вашим RSA открытый ключ.

Вы можете найти код для таких вещей в моем блоге .

0 голосов
/ 20 апреля 2018

У меня была такая же проблема, потому что я поместил это в свой файл Global.asax, чтобы преобразовать URL-адрес в нижний регистр.

 protected void Application_BeginRequest(object sender, EventArgs e)
    {
      //   Don't rewrite requests for content (.png, .css) or scripts (.js)
        if (Request.Url.AbsolutePath.Contains("/Content/") ||
            Request.Url.AbsolutePath.Contains("/Scripts/"))
            return;

        If uppercase chars exist, redirect to a lowercase version
        var url = Request.Url.ToString();
       if (Regex.IsMatch(url, @"[A-Z]"))
        {
            Response.Clear();
           Response.Status = "301 Moved Permanently";
           Response.StatusCode = (int)HttpStatusCode.MovedPermanently;
            Response.AddHeader("Location", url.ToLower());
            Response.End();
       }
    }

Итак

Пример

Если шифрование выполняется с помощью строки base64, закодируйте ее как

http://localhost:11430/orderpreview?orderID=t4RZrnefb2a%253d&price=27.9

Затем при выполнении действия "Application_BeginRequest" преобразует его в

http://localhost:11430/orderpreview?orderID=t4rzrnefb2a%253d&price=27.9

Вы можете видеть, что RZ был преобразован в малый rz, это потерпит неудачу при расшифровке.

Решение

Внутри класса RouteConfig метод RegisterRoutes поместите его, если вы хотите, чтобы URL-адрес был в нижнем регистре

        routes.Canonicalize().Www();
        routes.Canonicalize().Lowercase();
        routes.Canonicalize().NoTrailingSlash();
...