Silverlight使用RSA加密socket tcp通讯数据

    在tcp通讯中为了数据安全在某些情况下对数据进行加密传输是很有必要的,可惜的是MS并没有为Silverlight提供一些标准的加密功能实现.如果你想在Silverlight中使用RSA或DES这些标准的加密算法,那真的不好意思MS并没有提供...不过我们可以使用一些基于Silverlight开源实现的加密库,以下就是一个开源的RSA加密库http://scrypt.codeplex.com.

    RSA是一种非对称加密算法,它提供数据加密和签名的功能.Rsa的加解密都用不同的密钥,所以即使你有加密的密钥也无法对加密的数据进行解密(相对解密成本).如果想破解加密数据那必须要把别一方的密钥破解,想分解RSA 2048位的密钥基本是不可能的事情.下面通过简单的例子来运RSA进行数据加密传输.

    在编写代码之前先整理一下流程,假设我们需要加密提供给服务器的数据,那么我们必须向服务获取一个RSA的公钥,而密钥则保留在服务器端.客户端只需要采用公钥进行数据加密;服务器用私钥进行数据解密就OK了.

    以下是制定简单的通讯协议

public class GetKey:Beetle.IMessage
    {
        public void Load(Beetle.BufferReader reader)
        {
           
        }
        public void Save(Beetle.BufferWriter writer)
        {
           
        }
    }
    public class GetKeyResponse:Beetle.IMessage
    {
        public string PublicKey;
        public void Load(Beetle.BufferReader reader)
        {
            PublicKey = reader.ReadString();
        }

        public void Save(Beetle.BufferWriter writer)
        {
            writer.Write(PublicKey);
        }
    }

    分别是获取密钥请求和应答

    服务器端只需要根据连接创建一个新的RSA 2048加密对象,并把密钥导出到XML中,注意导出的时候只导公钥部分就行了

private RSACryptoServiceProvider GetRsa(TcpChannel channel)
        {
            string key = "_RSA";
            RSACryptoServiceProvider result = (RSACryptoServiceProvider)channel[key];
            if (result == null)
            {
                result = new RSACryptoServiceProvider(2048);
                channel[key] = result;
            }
            return result;
        }
        public void GetKey(TcpChannel channel, GetKey e)
        {
            GetKeyResponse response = new GetKeyResponse();
            response.PublicKey = GetRsa(channel).ToXmlString(false);
            channel.Send(response);
            Console.WriteLine("{0} Get PublicKey!", channel.EndPoint);
        }

    Silverlight在接收到公钥数据只需要把他导入到对应的RSA对象中

public void Response(Beetle.TcpChannel channel, GetKeyResponse e)
        {
            RSACrypto.FromXmlString(e.PublicKey);
            Dispatcher.BeginInvoke(() =>
            {
                txtStatus.Content = "获取公钥成功!";
                cmdRegister.IsEnabled = true;
            });
        }

    导入之后就可以进行相应数据的加密工作

private void cmdRegister_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Register register = new Register();
                register.UserName = RSACrypto.Encrypt(Encoding.UTF8.GetBytes(txtUserName.Text));
                register.PassWord = RSACrypto.Encrypt(Encoding.UTF8.GetBytes(txtPassWord.Text));
                Channel.Send(register);
            }
            catch (Exception e_)
            {
                txtStatus.Content = e_.Message;
            }
        }

   服务器接收数据后进行相关解密工作

public void Register(TcpChannel channel, Register e)
        {
            Console.WriteLine("username:{0}", Smark.Core.Functions.ToString(e.UserName));
            Console.WriteLine("password:{0}", Smark.Core.Functions.ToString(e.PassWord));
            Console.WriteLine("username:{0}", Encoding.UTF8.GetString(GetRsa(channel).Decrypt(e.UserName,true)));
            Console.WriteLine("password:{0}", Encoding.UTF8.GetString(GetRsa(channel).Decrypt(e.PassWord, true)));
        }

   解密数据对比

    理解流程后使用RAS对通信数据加密是件很简单的事情,由于RSA加密数据效率不高,所以对于大量通讯数据一般不采用RSA来处理.这个时候可以采用对称加密来处理,但对称加密有个缺点就是加解密钥是一样的,为了保证密钥在传输的过程中不易被获取所以一般都会采用RSA对密钥进行加密.

   下载完全代码

Rsa.rar (1.08 mb)

posted @ 2012-04-13 11:44  beetlex  阅读(2848)  评论(1编辑  收藏  举报