zoukankan      html  css  js  c++  java
  • 通过RSA进行私钥加密公钥解密算法的进一步改进

    正在做一个软件需要用到非对称加密算法进行注册信息的加密,没想到的是RSA只能用公钥加密私钥解密,这和我的需求正好相反,于是在网上找到了牛人做的加密算法,可在使用后发现,对中文的支持有问题。

    原文地址:http://www.cnblogs.com/hhh/archive/2011/06/03/2070692.html

    原来的算法将输入字符串按每段128个字符进行拆解,可是如果在拆分的位置上正好有中文,解密之后就会出现乱码,甚是头疼。

    仔细研究过算法以后,发现原先以字符串方式来处理数据的方式并不合理,于是重写了算法,以二进制方式处理,成功解决了乱码的问题,以下是改进之后的算法。

            public static byte[] Encrypt(byte[] data, BigInteger d, BigInteger n)
            {
                int size = 128;
                byte[] buffer = new byte[size];
    
                using (MemoryStream source = new MemoryStream(data))
                using (MemoryStream output = new MemoryStream())
                {
                    int bytes;
    
                    while ((bytes = source.Read(buffer, 0, size)) > 0)
                    {
                        BigInteger bi1 = new BigInteger(buffer, bytes);
                        BigInteger bi2 = bi1.modPow(d, n);
    
                        data = bi2.getBytes();
                        System.Diagnostics.Debug.Assert(data.Length < 256);
                        output.WriteByte((byte)data.Length);
                        output.Write(data, 0, data.Length);
                    }
    
                    return output.ToArray();
                }
            }
    
            public static byte[] Decrypt(byte[] data, BigInteger e, BigInteger n)
            {
                using (MemoryStream input = new MemoryStream(data))
                using (MemoryStream output = new MemoryStream())
                {
                    int length;
    
                    while ((length = input.ReadByte()) >= 0)
                    {
                        byte[] buffer = new byte[length];
                        if (input.Read(buffer, 0, length) != length)
                            throw new InvalidDataException();
    
                        BigInteger bi1 = new BigInteger(buffer);
                        BigInteger bi2 = bi1.modPow(e, n);
    
                        buffer = bi2.getBytes();
    
                        output.Write(buffer, 0, buffer.Length);
                    }
    
                    return output.ToArray();
                }
            }
    
            public static string Encrypt(string source, string d, string n)
            {
                byte[] N = Convert.FromBase64String(n);
                byte[] D = Convert.FromBase64String(d);
                BigInteger biN = new BigInteger(N);
                BigInteger biD = new BigInteger(D);
    
                byte[] data = System.Text.Encoding.UTF8.GetBytes(source);
                data = Encrypt(data, biD, biN);
    
                return Convert.ToBase64String(data);
            }
    
            public static string Decrypt(string source, string e, string n)
            {
                byte[] N = Convert.FromBase64String(n);
                byte[] E = Convert.FromBase64String(e);
                BigInteger biN = new BigInteger(N);
                BigInteger biE = new BigInteger(E);
                
                byte[] data = Convert.FromBase64String(source);
                data = Decrypt(data, biE, biN);
    
                return System.Text.Encoding.UTF8.GetString(data);
            }  

    最后,感谢原作者的努力,让我省了好多事。

    参考文章:

    【1】RSA私钥加密公钥解密算法

    【2】C#使用RSA私钥加密公钥解密的改进,解决特定情况下解密后出现乱码的问题

    【3】BigInteger大整数运算类

  • 相关阅读:
    技巧篇:如何重写基类的事件
    技巧篇:结合反射技术实现多算法动态加密
    C语言关键字 专一王子:volatile
    第一章 C语言关键字 auto和register
    程序员的进化
    C语言关键字 铁布衫:const
    LINQ简记(3):子句
    windows phone开发之获取屏幕分辨率 和 系统版本
    windows phone开发之 listbox分页加载数据
    Windows phone 微博客户端 开发之项目总结
  • 原文地址:https://www.cnblogs.com/effun/p/3033382.html
Copyright © 2011-2022 走看看