首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用RSA私钥解密较大的文本

问使用RSA私钥解密较大的文本
EN

Stack Overflow用户
提问于 2013-02-08 11:24:53
回答 2查看 2.2K关注 0票数 0

我必须使用RSA公钥和私钥加密和解密一个大字符串。我已经成功地使用以下示例代码加密了更大的文本

代码语言:javascript
复制
public static string Encrypt(string publicKey, string data, RsaKeyLengths length)
        {
            // full array of bytes to encrypt
            byte[] bytesToEncrypt;

            // worker byte array
            byte[] block;

            // encrypted bytes
            byte[] encryptedBytes;

            // length of bytesToEncrypt
            var dataLength = 0;

            // number of bytes in key                
            var keySize = 0;

            // maximum block length to encrypt          
            var maxLength = 0;

            // how many blocks must we encrypt to encrypt entire message?
            var iterations = 0;

            // the encrypted data
            var encryptedData = new StringBuilder();

            // instantiate the crypto provider with the correct key length
            var rsaCryptoServiceProvider = new RSACryptoServiceProvider((int)length);

            // initialize the RSA object from the given public key
            rsaCryptoServiceProvider.FromXmlString(publicKey);

            // convert data to byte array
            bytesToEncrypt = Encoding.Unicode.GetBytes(data);

            // get length of byte array
            dataLength = bytesToEncrypt.Length;

            // convert length of key from bits to bytes
            keySize = (int)length / 8;

            // .NET RSACryptoServiceProvider uses SHA1 Hash function
            // use this to work out the maximum length to encrypt per block
            maxLength = ((keySize - 2) - (2 * SHA1.Create().ComputeHash(bytesToEncrypt).Length));

            // how many blocks do we need to encrypt?
            iterations = dataLength / maxLength;

            // encrypt block by block
            for (int index = 0; index <= iterations; index++)
            {
                // is there more than one full block of data left to encrypt?
                if ((dataLength - maxLength * index) > maxLength)
                {
                    block = new byte[maxLength];
                }
                else
                {
                    block = new byte[dataLength - maxLength * index];
                }

                // copy the required number of bytes from the array of bytes to encrypt to our worker array
                Buffer.BlockCopy(bytesToEncrypt, maxLength * index, block, 0, block.Length);

                // encrypt the current worker array block of bytes
                encryptedBytes = rsaCryptoServiceProvider.Encrypt(block, true);

                // RSACryptoServiceProvider reverses the order of encrypted bytesToEncrypt after encryption and before decryption.
                // Undo this reversal for compatibility with other implementations
                Array.Reverse(encryptedBytes);

                // convert to base 64 string
                encryptedData.Append(Convert.ToBase64String(encryptedBytes));

            }
            return encryptedData.ToString();

        }

然后,我尝试使用以下代码解密更大的文本

代码语言:javascript
复制
/// <summary>
        /// Encrypt an arbitrary string of data under the supplied public key
        /// </summary>
        /// <param name="publicKey">The public key to encrypt under</param>
        /// <param name="data">The data to encrypt</param>
        /// <param name="length">The bit length or strength of the public key: 1024, 2048 or 4096 bits. This must match the 
        /// value actually used to create the publicKey</param>
        /// <returns></returns>
        public static string Decrypt(string privateKey, string data, RsaKeyLengths length)
        {
            // full array of bytes to encrypt
            byte[] bytesToDecrypt;

            // worker byte array
            byte[] block;

            // encrypted bytes
            byte[] decryptedBytes;

            // length of bytesToEncrypt
            var dataLength = 0;

            // number of bytes in key                
            var keySize = 0;

            // maximum block length to encrypt          
            var maxLength = 0;

            // how many blocks must we encrypt to encrypt entire message?
            var iterations = 0;

            // the encrypted data
            var decryptedData = new StringBuilder();

            // instantiate the crypto provider with the correct key length
            var rsaCryptoServiceProvider = new RSACryptoServiceProvider((int)length);

            // initialize the RSA object from the given public key
            rsaCryptoServiceProvider.FromXmlString(privateKey);

            // convert data to byte array
            bytesToDecrypt = Encoding.Unicode.GetBytes(data);

            // get length of byte array
            dataLength = bytesToDecrypt.Length;

            // convert length of key from bits to bytes
            keySize = (int)length / 8;

            // .NET RSACryptoServiceProvider uses SHA1 Hash function
            // use this to work out the maximum length to encrypt per block
            //maxLength = ((keySize - 2) - (2 * SHA1.Create().ComputeHash(bytesToDecrypt).Length));
            maxLength = ((keySize / 8) % 3 != 0) ?
              (((keySize / 8) / 3) * 4) + 4 : ((keySize / 8) / 3) * 4; ;

            // how many blocks do we need to encrypt?
            iterations = dataLength / maxLength;

            // encrypt block by block
            for (int index = 0; index <= iterations; index++)
            {
                // is there more than one full block of data left to encrypt?
                if ((dataLength - maxLength * index) > maxLength)
                {
                    block = new byte[maxLength];
                }
                else
                {
                    block = new byte[dataLength - maxLength * index];
                }

                // copy the required number of bytes from the array of bytes to encrypt to our worker array
                Buffer.BlockCopy(bytesToDecrypt, maxLength * index, block, 0, block.Length);

                // encrypt the current worker array block of bytes
                decryptedBytes = rsaCryptoServiceProvider.Decrypt(block, true);

                // RSACryptoServiceProvider reverses the order of encrypted bytesToEncrypt after encryption and before decryption.
                // Undo this reversal for compatibility with other implementations
                Array.Reverse(decryptedBytes);

                // convert to base 64 string
                decryptedData.Append(Convert.ToBase64String(decryptedBytes));

            }
            return decryptedData.ToString();
        }

实际上加密进行得很顺利。没问题。但当我试图解密的时候。我得到以下异常

未处理异常:解码OAEP填充时发生System.Security.Cryptography.CryptographicException:错误。

有人能帮我吗?

EN

回答 2

Stack Overflow用户

发布于 2013-02-08 11:34:03

使用流密码代替,并只加密该密钥的这个密码与RSA。如果您需要RSA,这可能会有所帮助,因为RSA的公钥逻辑,并希望使用不同的密钥进行加密和解密。使用流密码,您将能够加密和解密千兆字节的数据,没有问题。

RSA通常不用于大量的数据。

票数 1
EN

Stack Overflow用户

发布于 2013-03-26 18:42:26

也许有点晚了,但我发现http://tekaris.com/blog/2013/02/08/encrypting-large-data-with-asymetric-rsacryptoserviceprovider/很有帮助。这里的诀窍显然是拆分数据,加密和重新加入数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14771483

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档