"Плохие Данные" CryptographicException

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

   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.Расшифровать.

спасибо }

4 ответов


  • преобразование открытого текста взад и вперед с помощью Строковой кодировки (т. е. 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);
    }
}

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

не шифротекст обратно через строку кодировки

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

...

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

...

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

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


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

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

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


у меня была такая же проблема, потому что я поместил это в свой глобальный.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 & цена=27.9

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

http://localhost:11430/orderpreview?orderID=t4rzrnefb2a%253d & цена=27.9

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

решение

внутри метода Routeconfig class RegisterRoutes поместите это, если вы хотите url в нижнем регистре

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