数据传输(Rpc)安全层协议设计方案

1 摘要

目前服务和服务之间通过Rpc方式进行数据交互,但数据在传输的时候为明文,对于整个平台而言可能存在数据被拦截、篡改、破坏等风险。因为需要提出一种共同遵守的约定,保证数据传输的安全性。

2 方案

主要是通过对传输前加密,数据接收后解密的方式实现传输安全保护。

2.1 方案一 对称加密

在这里插入图片描述

原理

1、发送端和接收端持有相同的密钥,发送端将需要发送的数据用密钥key加密,接收端用密钥Key解密得到数据。

优点

1、安全随着密钥的复杂度加大,被破解的难度急剧上升,保证了数据的安全;
2、速度快
3、实现简单

缺点

密钥需要提前约定,如果任意一方泄漏key那么整个服务集群的数据传输将变得不安全。

算法

DES、3DES、AES、RC5、RC6

2.2 方案二 公钥加密

在这里插入图片描述

原理

1、 发送端用接收端的公钥加密数据;
2、 接收端用自身的私钥解密密文获得数据。

优点

相对对于对称加密算法,在传输过程中就算数据被窃取也不会有什么问题,因为只有公钥对应的私钥才能解密密文

缺点

1、 对比堆成加密来说,运行速度慢很多
2、 有实现难度

算法

RSA

2.3 方案三 对称加密、公钥加密混合模式

在这里插入图片描述

原理

  1. 发送端向接收方申请连接;
  2. 接收方发送自身公钥;
  3. 发送方将自身的公钥用接收方的公钥加密并发送非接收方;
  4. 接收方将发送方的密文解密后得到发送方的公钥,并将对称加密的key加密后发给发送方;
  5. 发送方收到消息验证消息的正确性,如果正确则认为接收方是可信的,并在之后的发送消息活动中都用这个key进行数据加密。

利用公钥加密方式动态获取对称加密的密钥,用于对称加密,第二步、第三步够让发送方确认接收方是正确的,而不是冒牌的。

优点

结合了公钥加密和对称加密算法的优点,并且增加了公钥的拥有者的身份鉴别,安全、高效

缺点

实现复杂

算法

RSA+ DES(或3DES、AES、RC5、RC6)

3 实验

实验一 DES和RSA性能对比

对比项加密解密加密解密
执行次数\算法\消耗(ms)DESRSADESRSA
10121
1055710
100545956101
1000574577499943
100004971510947899341
10000048591534175387693848
1000000485881510226480218930679

在这里插入图片描述

分析

DES和RSA加密性能相差不大,RSA慢一点可忽略不计,而解密相差很大,DES比RSA快一倍。

4 总结

对性能有较高要求采取对称加密,从安全的角度会选择公钥加密算法,而时间的充裕程度对安全和性能都有较高要求,则建议采取第三个方案,混合式加密技术,既保证通信的安全性也能有很好的性能表现。

附录

测试代码

1. DESCryption.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using static System.Text.Encoding;
using Convert = System.Convert;

namespace ConsoleApp.Encryption
{
    public class DESCryption
    {
        private const string KEY_64 = "";//必须是8位无符号字符串
        private const string IV_64 = "";
        /// <summary>
        /// DSE加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string Encode(string str)
        {
            byte[] byKey = UTF8.GetBytes(KEY_64);
            byte[] byIV = UTF8.GetBytes(IV_64);
            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
            int i = cryptoProvider.KeySize;
            MemoryStream ms = new MemoryStream();
            CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);

            StreamWriter sw = new StreamWriter(cst);
            sw.Write(str);
            sw.Flush();
            cst.FlushFinalBlock();
            sw.Flush();
            return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);

        }
        /// <summary>
        /// DSE解密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string Decode(string str)
        {
            byte[] byKey = UTF8.GetBytes(KEY_64);
            byte[] byIV = UTF8.GetBytes(IV_64);
            byte[] byEnc;
            try
            {
                byEnc = Convert.FromBase64String(str);
            }
            catch
            {
                return null;
            }
            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
            MemoryStream ms = new MemoryStream(byEnc);
            CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
            StreamReader sr = new StreamReader(cst);
            return sr.ReadToEnd();
        }
    }
}

2. RSACryption.cs
using Consul;
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

namespace ConsoleApp.Encryption
{
    public class RSACryption
    {
        /// <summary>
        /// 生成一对公钥和私钥
        /// </summary>
        /// <returns></returns>
        public static KeyValuePair<string, string> GetKeyPairCspBlob()
        {
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
            string public_Key = Convert.ToBase64String(RSA.ExportCspBlob(false));
            string private_Key = Convert.ToBase64String(RSA.ExportCspBlob(true));
            return new KeyValuePair<string, string>(public_Key, private_Key);
        }
        /// <summary>
        /// 生成一对公钥和私钥
        /// </summary>
        /// <returns></returns>
        public static KeyValuePair<string, string> GetKeyPairXmlString()
        {
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
            string public_Key = RSA.ToXmlString(false);
            string private_Key = RSA.ToXmlString(true);
            return new KeyValuePair<string, string>(public_Key, private_Key);
        }


        /// <summary>
        /// DSE加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string EncodeXmlString(string str,string publicKey)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            
            byte[] cipherbytes;
            rsa.FromXmlString(publicKey);
            cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(str), false);

            return Convert.ToBase64String(cipherbytes);
        }
        /// <summary>
        /// DSE解密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string DecodeXmlString(string str,string privateKey)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            byte[] cipherbytes;
            rsa.FromXmlString(privateKey);
            cipherbytes = rsa.Decrypt(Convert.FromBase64String(str), false);

            return Encoding.UTF8.GetString(cipherbytes);
        }
    }
}

3. Program.cs
using ConsoleApp.Encryption;
using System;
using System.Diagnostics;
using System.Threading;

namespace ConsoleApp
{
    class Program
    {

        static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();
            var RSAKeyPiar = RSACryption.GetKeyPairXmlString();
            var RSAPublicKey = RSAKeyPiar.Key;
            var RSAPrivateKey = RSAKeyPiar.Value;

            string plainText = Newtonsoft.Json.JsonConvert.SerializeObject(new { Name="admin",Sex = 1,BirthDay = DateTime.Now.AddYears(-20),Address="广东省深圳市" });
            string DesCiphertext = DESCryption.Encode(plainText);
            string RSACliphertext = RSACryption.EncodeXmlString(plainText, RSAPublicKey);
            
            int runNumber = 1000000;
            Console.WriteLine($"执行{runNumber}次,消耗时间单位-毫秒");

            stopwatch.Start();
            for (int i = 0; i < runNumber; i++)
            {
                var desCiphertextTemp = DESCryption.Encode(plainText);
            }
            stopwatch.Stop();
            Console.WriteLine("DES加密消耗:"+stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();
            stopwatch.Start();
            for (int i = 0; i < runNumber; i++)
            {
                var desCiphertextTemp = RSACryption.EncodeXmlString(plainText, RSAPublicKey);
            }
            stopwatch.Stop();
            Console.WriteLine("RSA加密消耗:" + stopwatch.ElapsedMilliseconds);

            Console.WriteLine("------------------------------");

            stopwatch.Reset();
            stopwatch.Start();
            for (int i = 0; i < runNumber; i++)
            {
                var desCiphertextTemp = DESCryption.Decode(DesCiphertext);
            }
            stopwatch.Stop();
            Console.WriteLine("DES解密消耗:" + stopwatch.ElapsedMilliseconds);


            stopwatch.Reset();
            stopwatch.Start();
            for (int i = 0; i < runNumber; i++)
            {
                var desCiphertextTemp = RSACryption.DecodeXmlString(RSACliphertext, RSAPrivateKey);
            }
            stopwatch.Stop();
            Console.WriteLine("RSA解密消耗:" + stopwatch.ElapsedMilliseconds);

            Console.ReadKey();
        }
    }
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值