RSA数据解密错误。要解密的数据超过此64字节模数的最大值

时间:2009-05-20 10:15:14

标签: asp.net

在使用rsa提供程序加密和描述字符串时,我收到此错误。

RSA数据解密错误。要解密的数据超过此64字节模数的最大值。

任何人都知道如何解决这个错误吗?


    internal sealed class RSAProvider
    {
        #region key store class

        [Serializable]
            private struct rsaKey
        {
            public rsaKey(RSAParameters rsaKeyInfo)
            {
                D = rsaKeyInfo.D;
                DP = rsaKeyInfo.DP;
                DQ = rsaKeyInfo.DQ;
                Exponent = rsaKeyInfo.Exponent;
                InverseQ = rsaKeyInfo.InverseQ;
                Modulus = rsaKeyInfo.Modulus;
                P = rsaKeyInfo.P;
                Q = rsaKeyInfo.Q;
            }

            public RSAParameters CreateRSAKey()
            {
                RSAParameters rsaKeyInfo = new RSAParameters();

                rsaKeyInfo.D = D;
                rsaKeyInfo.DP = DP;
                rsaKeyInfo.DQ = DQ;
                rsaKeyInfo.Exponent = Exponent;
                rsaKeyInfo.InverseQ = InverseQ;
                rsaKeyInfo.Modulus = Modulus;
                rsaKeyInfo.P = P;
                rsaKeyInfo.Q = Q;

                return rsaKeyInfo;
            }

            public byte[] D;
            public byte[] DP;
            public byte[] DQ;
            public byte[] Exponent;
            public byte[] InverseQ;
            public byte[] Modulus;
            public byte[] P;
            public byte[] Q;
        }

        #endregion

        private static RSAParameters rsaKeyParameters;

        static RSAProvider()
        {
            string rsaKeyString = System.Configuration.ConfigurationSettings.AppSettings["RSAKey"];
            if(rsaKeyString != null)
            {
                rsaKeyParameters = GetKeyByString(rsaKeyString);
            }
        }

        private RSAProvider()
        {
        }

        private static RSAParameters RSAKeyInfo
        {
            get
            {
                return rsaKeyParameters;
            }
        }

        private static bool DoOAEPPadding
        {
            get
            {
                return false;
            }
        }

        public static string GenerateKey(int keySize)
        {
            //Create a new instance of RSACryptoServiceProvider to generate
            //public and private key data.
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(keySize);

            RSAParameters rsaKeyInfo = RSA.ExportParameters(true);

            return GetKeyString(rsaKeyInfo);
        }


        #region Encrypt

        public static byte[] Encrypt(byte[] dataToEncrypt, string rsaKeyString)
        {
            RSAParameters rsaKeyInfo = GetKeyByString(rsaKeyString);

            return Encrypt(dataToEncrypt, rsaKeyInfo);
        }

        public static byte[] Encrypt(byte[] dataToEncrypt, RSAParameters rsaKeyInfo)
        {
            try
            {   
                //Create a new instance of RSACryptoServiceProvider.
               // Common.Identity.ImpersonateValidUser("prana", "eetplpvt", "Avdhoota1985");
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

                //Import the RSA Key information. This only needs
                //toinclude the public key information.
                RSA.ImportParameters(rsaKeyInfo);

                //Encrypt the passed byte array and specify OAEP padding.  
                //OAEP padding is only available on Microsoft Windows XP or
                //later.  
                //return RSA.Encrypt(dataToEncrypt, DoOAEPPadding);
                byte[] data = RSA.Encrypt(dataToEncrypt, DoOAEPPadding);
                RSA.Clear();
                //Common.Identity.UndoImpersonation();
                return data;
            }
                //Catch and display a CryptographicException  
                //to the console.
            catch(CryptographicException e)
            {
                // Updated By Divya Bhalodia on 27th June 2008 for Localization task
                //throw new Exception("Data encryption error.", e);
                Common.EnumLocalization.EnumLocalization loc = new Common.EnumLocalization.EnumLocalization(ASP.BL.ApplicationUsers.ApplicationUserController.CurrentUserCulture.Code, ASP.BL.Applications.ApplicationController.CurrentApplicationInfo.ItemId);
                throw new Exception(loc.LocalizeString("RSA Data encryption error.") + e.Message, e);
                // end Updated - Divya
            }
        }

        public static byte[] Encrypt(byte[] dataToEncrypt)
        {
            return Encrypt(dataToEncrypt, RSAKeyInfo);
        }

        #endregion

        #region Decrypt

        public static byte[] Decrypt(byte[] dataToDecrypt, string rsaKeyString, bool doOAEPPadding)
        {
            RSAParameters rsaKeyInfo = GetKeyByString(rsaKeyString);
            return Decrypt(dataToDecrypt, rsaKeyInfo, doOAEPPadding);
        }

        public static byte[] Decrypt(byte[] dataToDecrypt, RSAParameters rsaKeyInfo, bool doOAEPPadding)
        {
            try
            {
                //Create a new instance of RSACryptoServiceProvider.
                Common.Identity.ImpersonateValidUser();
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

                //Import the RSA Key information. This needs
                //to include the private key information.
                RSA.ImportParameters(rsaKeyInfo);

                //Decrypt the passed byte array and specify OAEP padding.  
                //OAEP padding is only available on Microsoft Windows XP or
                //later.  
                //return RSA.Decrypt(dataToDecrypt, doOAEPPadding);
                byte[] data = RSA.Decrypt(dataToDecrypt, doOAEPPadding);
                RSA.Clear();
                Common.Identity.UndoImpersonation();
                return data;
            }
                //Catch and display a CryptographicException  
                //to the console.
            catch(CryptographicException e)
            {

                // Updated By Divya Bhalodia on 27th June 2008 for Localization task
                //throw new Exception("Data decryption error.", e);
                Common.EnumLocalization.EnumLocalization loc = new Common.EnumLocalization.EnumLocalization(ASP.BL.ApplicationUsers.ApplicationUserController.CurrentUserCulture.Code, ASP.BL.Applications.ApplicationController.CurrentApplicationInfo.ItemId);
                throw new Exception(loc.LocalizeString("RSA Data decryption error.") + e.Message, e);
                // end Updated - Divya
            }
        }

        public static byte[] Decrypt(byte[] dataToDecrypt)
        {
            return Decrypt(dataToDecrypt, RSAKeyInfo, DoOAEPPadding);
        }
        #endregion

        #region Additional functions

        private static string GetKeyString(RSAParameters rsaKeyInfo)
        {
            byte[] tmp;
            rsaKey k = new rsaKey(rsaKeyInfo);
            BinaryFormatter formater = new BinaryFormatter();

            using(MemoryStream stream = new MemoryStream())
            {
                formater.Serialize(stream, k);
                tmp = stream.ToArray();
            }

            Code(tmp);

            return Convert.ToBase64String(tmp);
        }


        private static RSAParameters GetKeyByString(string rsaKeyString)
        {
            rsaKey k;

            byte[] tmp = Convert.FromBase64String(rsaKeyString);
            Code(tmp);

            BinaryFormatter formater = new BinaryFormatter();

            using(MemoryStream stream = new MemoryStream(tmp))
            {
                k = (rsaKey)formater.Deserialize(stream);
            }
            return k.CreateRSAKey();
        }


        private static void Code(byte[] tmp)
        {
            byte mask1 = 0x55;
            byte mask3 = 0xB9;
            byte mask4 = 0xCF;

            for(int i = 0; i 

1 个答案:

答案 0 :(得分:0)

我遇到了类似的问题,但你可以做两件事来帮助自己克服它们。

  1. 您需要确保加密的数据比您使用的密钥短。因此,如果你的密钥是1024位,那么请确保你只是说1000比特的低音。为此,您需要将字节数组块分块为较小的块,加密每个块,然后将加密值存储在数组或字符串中。因此,不是加密1个字符串,而是加密说5个字符串。
  2. 当以字符串形式存储此信息时,请确保所有数字都是相同的长度,因此如果格式化程序返回15,则将字符串存储为015,以便稍后除以3以获取字节然后放入数组中

    要解密数据,您只需读取字符串的长度并确定要解密的块数。逐个破坏这些,然后您可以使用已损坏的字节数组重新创建对象。

    如果您想要实际代码,请亲自与我联系,我将能够通过一些可以为您完成此操作的脚本帮助您。