当前位置:编程学习 > 网站相关 >>

C#使用RSA私钥加密公钥解密的改进

先看加密方法:


private string EncryptString(string source, BigInteger d, BigInteger n)
        {
            int len = source.Length;
            int len1 = 0;
            int blockLen = 0;
            if ((len % 128) == 0)
                len1 = len / 128;
            else
                len1 = len / 128 + 1;
            string block = "";
            string temp = "";
            for (int i = 0; i < len1; i++)
            {
                if (len >= 128)
                    blockLen = 128;
                else
                    blockLen = len;
                block = source.Substring(i * 128, blockLen);
                byte[] oText = System.Text.Encoding.Default.GetBytes(block);
                BigInteger biText = new BigInteger(oText);
                BigInteger biEnText = biText.modPow(d, n);
                string temp1 = biEnText.ToHexString();
                temp += temp1;
                len -= blockLen;
            }
            return temp;
        }

 

由于RSA算法单次加密只能支持128byte的数据,如果数据长度超过128byte,就会被分割为几段进行加密,最后把加密结果转换为16进制字符串,并连接起来输出结果。

一般情况下,128byte的数据,加密后输出的hex字符串应该是256byte,所以对应的解密方法为:把加密后的hex字符串按256byte进行拆分,分别解密,最后得到原文。方法如下:

 


private string DecryptString(string source, BigInteger e, BigInteger n)
        {
            int len = source.Length;
            int len1 = 0;
            int blockLen = 0;
            if ((len % 256) == 0)
                len1 = len / 256;
            else
                len1 = len / 256 + 1;
            string block = "";
            string temp = "";
            for (int i = 0; i < len1; i++)
            {
                if (len >= 256)
                    blockLen = 256;
                else
                    blockLen = len;
                block = source.Substring(i * 256, blockLen);
                BigInteger biText = new BigInteger(block, 16);
                BigInteger biEnText = biText.modPow(e, n);
                string temp1 = System.Text.Encoding.Default.GetString(biEnText.getBytes());
                temp += temp1;
                len -= blockLen;
            }
            return temp;
        }

 

 这个算法一般来讲是没问题的,但问题就在于,对于128byte的数据,BigInteger类输出的加密后的hex字符串,并不一定是256byte。所以,解密的时候按照256byte进行拆分,就会出现字符串拆分不正确,最终导致解密失败,解密出来的结果是乱码。

 

我们来看看BigInteger类的ToHexString()方法,其实现如下:


public string ToHexString()
        {
            string result = data[dataLength - 1].ToString("X");

            for (int i = dataLength - 2; i >= 0; i--)
            {
                result += data[i].ToString("X8");
            }

            return result;
        }

 

 对于128byte的BigInteger,此方法返回的结果并不一定是256byte。

 

简单的解决办法,就是把这个方法的第一行,ToString("X")改为ToString("X8"),修改后的方法如下:


public string ToHexString()
        {
            string result = data[dataLength - 1].ToString("X8");

            for (int i = dataLength - 2; i >= 0; i--)
            {
                result += data[i].ToString("X8");
            }

            return result;
        }

 

这样改虽然可以解决问题,但属于治标不治本的方法,因为这样改,也不能保证输出的字符串就是256byte, 最靠谱的方法是改进加密方法和解密方法。


 

加密方法的改进:


由于加密后的

补充:综合编程 , 安全编程 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,