C语言单片和C#语言服务器端DES及3DES加密的实现

简介: 原文:C语言单片和C#语言服务器端DES及3DES加密的实现公司最近在做单片机和C#语言的通信。用的是Socket通信。传输的数据是明文,后来 在会上讨论准备用DES加密(对称加密)来做。 双方约定 相应的“密钥”。
原文: C语言单片和C#语言服务器端DES及3DES加密的实现

公司最近在做单片机和C#语言的通信。用的是Socket通信。传输的数据是明文,后来 在会上讨论准备用DES加密(对称加密)来做。

双方约定 相应的“密钥”。

以前做的加密一般都是用C#加密和C#解密。一直以为是个简单的问题,现在和用C写的单片机通信的时候却出了问题。

问题是什么呢?

我找了几个在线加密 解密的网站,还下了几个加密解密的工具。结果相同的数据,用相同的密钥却得到不同的结果。

而且现在网上C语言实现的DES资料基本上是不靠谱,好多是错误的,都是你抄我,我抄你,抄来抄去,抄到最后没有一个完整实现DES几种模式加密的。

没办法,赶紧去找DES的原理来看,好研究了一番现在终于解决完成。保证了自己写的代码和几种工具一样的结果。现在将代码奉上,希望能帮上大家的忙。

一,ECB模式
ECB(Electronic Code book电码本)模式,相对简单,将数据按照每8字节一段进行DES加解密的(一次加解密操作必须是8字节,这是算法决定的),如果最后一段不足8字节, 则按照需要补0x00或者0xFF进行计算.之后按照数据顺序将所有的数据连接在一起。

这个模式说了这么多,我也不明白啥意思,不过 现在网上流传的C语言实现的DES加密算法基本上都是这种模式。

采用这个模式以后 ,设置不设置 加密向量都没有用的。

请注意,我在这里实现的都是 采用这种模式,所以 文中出现的加密向量有关的语句,你都可以把它给无视掉,你删除掉它,也会得到相同的结果。
二,CBC模式
CBC(Cipher-block chaining密文分组链接)模式,该模式使得各段数据存在一些联系,实现原理比较复杂,我也没有搞懂,不过以前写C#代码的时候,有个加密向量,就像下面代码这样子的Byte数组

 

  private static byte[] IV = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };

 

 

 

我一直不明白它有什么用,现在我终于明白了,C#默认的就是这种模式。

现在奉上C#的实现代码:

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "abcdefgh";
            string str1 = "1234567887654321";

            string str2 = DES3Encrypt(str, str1);
            Console.WriteLine(str2);

            Console.WriteLine(DES3Decrypt(str2, str1));
        }


        #region DES加解密

        private static byte[] IV = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };///这段代码可以删除掉
        //默认密钥向量
        //private static byte[] IV = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01 };
        /// <summary>
        /// DES加密
        /// </summary>
        /// <param name="input">待加密的字符串</param>
        /// <param name="key">加密密钥</param>
        /// <returns></returns>
        public static string Encrypt(string pToEncrypt, string sKey)
        {
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            provider.Mode = CipherMode.CBC;
            //provider.Padding = PaddingMode.None;
            byte[] bytes = Encoding.Default.GetBytes(pToEncrypt);
            provider.Key = Encoding.ASCII.GetBytes(sKey);
            provider.IV = Encoding.ASCII.GetBytes(sKey);

            /* 创建一个内存流对象 */
            MemoryStream stream = new MemoryStream();

            /* 创建一个加密流对象 */
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateEncryptor(), CryptoStreamMode.Write);

            /* 将要加密的文本写到加密流中 */
            stream2.Write(bytes, 0, bytes.Length);

            /* 更新缓冲 */
            stream2.FlushFinalBlock();

            /* 获取加密过的文本 */
            StringBuilder builder = new StringBuilder();
            foreach (byte num in stream.ToArray())
            {
                builder.AppendFormat("{0:X2}", num);
            }
            stream2.Close();
            stream.Close();
            return builder.ToString();

            //return Convert.ToBase64String(stream.ToArray());

            //byte[] bytes4 = stream.ToArray();
            //string str=Encoding.Default.GetString(bytes4);
            //return str;
        }
        /// <summary>
        /// DES解密
        /// </summary>
        /// <param name="input">待解密的字符串</param>
        /// <param name="key">解密密钥,要求为8位,和加密密钥相同</param>
        /// <returns>解密成功返回解密后的字符串,失败返源串</returns>
        public static string Decrypt(string DecryptString, string Key)
        {
            try
            {
                //byte[] inputByteArray = Convert.FromBase64String(DecryptString);


                /** 
                 **将一个字符串转16进制字节数组而已
                 **/
                byte[] inputByteArray = new byte[DecryptString.Length / 2];
                for (int x = 0; x < DecryptString.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(DecryptString.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }
                //byte[] inputByteArray = Encoding.UTF8.GetBytes(DecryptString);

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                des.Mode = CipherMode.CBC;
                des.Padding = PaddingMode.None;

                des.Key = Encoding.ASCII.GetBytes(Key);
                des.IV = Encoding.ASCII.GetBytes(Key);


                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, des.CreateDecryptor(), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();

                mStream.Close();
                cStream.Close();
                return Encoding.Default.GetString(mStream.ToArray());
            }
            catch
            {
                return "";
            }
        }
        #endregion

        #region 3DES 加密解密

        public static string DES3Encrypt(string data, string key)
        {
            TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();

            //DES.GenerateKey();
            //byte[] cKey = DES.Key;

            DES.Key = ASCIIEncoding.ASCII.GetBytes(key);
            DES.Mode = CipherMode.ECB;
            DES.Padding = PaddingMode.None;

            ICryptoTransform DESEncrypt = DES.CreateEncryptor();

            byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(data);


            byte[] result = DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length);
            StringBuilder builder = new StringBuilder();
            foreach (byte num in result)
            {
                builder.AppendFormat("{0:X2}", num);
            }
            return builder.ToString();
            //return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
        }

        public static string DES3Decrypt(string DecryptString, string key)
        {
            TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
            //DES.GenerateKey();
            DES.Key = ASCIIEncoding.ASCII.GetBytes(key);
            DES.Mode = CipherMode.ECB;
            DES.Padding = PaddingMode.None;
            ICryptoTransform DESDecrypt = DES.CreateDecryptor();
            string result = "";
            try
            {
                //byte[] Buffer = Convert.FromBase64String(data);
                /*字符串转16进制字节数组*/
                byte[] inputByteArray = new byte[DecryptString.Length / 2];
                for (int x = 0; x < DecryptString.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(DecryptString.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }

                //byte[] Byteresult = DESDecrypt.TransformFinalBlock(inputByteArray, 0, inputByteArray.Length);
                //StringBuilder builder = new StringBuilder();
                //foreach (byte num in Byteresult)
                //{
                //    builder.AppendFormat("{0:X2}", num);
                //}
                //return builder.ToString();
                result = ASCIIEncoding.ASCII.GetString(DESDecrypt.TransformFinalBlock(inputByteArray, 0, inputByteArray.Length));
            }
            catch (Exception e)
            {
            }
            return result;
        }

        #endregion
    }
}

 

然后我们对比一下效果:

这是一个工具加密后的效果,使用的是DES。

要加密的字符串是:abcdefg

加密的密钥为:12345678

这是C#的加密 解密效果图:

 

OK一样的效果。

 

然后再把单片机那那边的实现效果给展示一下:

当然C语言版本的是我下载别人的代码,链接在这里

http://files.cnblogs.com/erwin/yxyDES2_C_Edition.rar

 

 

目录
相关文章
|
25天前
|
存储 安全 数据安全/隐私保护
oss服务器端加密
阿里云OSS提供服务器端加密,使用AES-256自动加密数据,保证上传至OSS的数据安全。下载时自动解密,透明处理。加密增强静态数据安全性,满足合规需求。支持OSS或KMS管理密钥,实现细粒度权限控制。确保云端对象数据全生命周期安全。
27 7
|
27天前
|
存储 安全 API
oss服务器端加密(Server-Side Encryption Configuration)
阿里云OSS提供服务器端加密(SSE),确保静态数据安全。支持SSE-KMS,使用KMS托管CMK加密。数据上传时自动加密,下载时自动解密。用户可设置Bucket默认加密或在上传时指定加密选项。适用于高度保护数据场景,如敏感个人信息和企业关键信息。兼容多种部署形态,特定特性地域可用。此功能简化了加密处理,增强了云端数据安全性。
30 1
|
29天前
|
算法 安全 C语言
使用C语言实现DES算法代码
使用C语言实现DES算法代码
|
1月前
|
数据挖掘 C# 开发工具
采用C#语言开发的全套医院体检系统PEIS源码功能介绍
体检系统,是专为体检中心/医院体检科等体检机构,专门开发的全流程管理系统,通过软件实现检测仪器数据自动提取,内置多级医生工作台,细化工作将体检检查结果汇总,生成体检报告登记到计算机系统中。通过软件系统进行数据分析统计与评判以及建立体检相关的体检档案。从而实现体检流程的信息化,提高工作效率,减少手动结果录入的一些常犯错误。 在实际应用中,医院体检系统能够解决传统体检中手工操作带来的问题,如工作量大、效率低下、易漏检、重检或错检等。通过与医院信息系统(如HIS、LIS、PACS等)的连接,系统能够满足体检中心的日常工作流程,提供更好的管理、统计和查询分析功能。同时,基于网络基础的系统可以在网上传输
22 1
|
5月前
|
开发框架 网络协议 前端开发
一个对C#程序混淆加密,小巧但够用的小工具
一个对C#程序混淆加密,小巧但够用的小工具
83 1
|
3月前
|
Android开发 数据安全/隐私保护
安卓逆向 -- FridaHook分析3DES加密值
安卓逆向 -- FridaHook分析3DES加密值
17 0
安卓逆向 -- FridaHook分析3DES加密值
|
4月前
|
算法 C# 数据安全/隐私保护
C# | 上位机开发新手指南(十)加密算法——ECC
本篇文章我们将继续探讨另一种非对称加密算法——ECC。 严格的说,其实ECC并不是一种非对称加密算法,它是一种基于椭圆曲线的加密算法,广泛用于数字签名和密钥协商。 与传统的非对称加密算法(例如RSA)不同,ECC算法使用椭圆曲线上的点乘法来生成密钥对和进行加密操作,而不是使用大数分解等数学算法。这使得ECC算法具有相同的安全性和强度,但使用更少的位数,因此在资源受限的环境中具有优势。 ECC算法虽然使用公钥和私钥进行加密和解密操作,但是这些操作是基于点乘法实现的,而不是基于大数分解等算法实现的。因此,ECC算法可以被视为一种非对称加密算法的变体,但是它与传统的非对称加密算法有所不同。
129 0
C# | 上位机开发新手指南(十)加密算法——ECC
|
4月前
|
XML 算法 安全
C# | 上位机开发新手指南(九)加密算法——RSA
RSA的特性 非对称性 RSA算法使用公钥和私钥两个不同的密钥,公钥用于加密数据,私钥用于解密数据。公钥可以公开,任何人都可以使用,而私钥只有密钥持有人可以访问。 安全性 RSA算法基于大数分解难题,即将一个大的合数分解成其质数因子的乘积。由于目前没有有效的算法可以在合理的时间内对大质数进行分解,因此RSA算法被认为是一种安全的加密算法。 可逆性 RSA算法既可以用于加密,也可以用于解密。加密和解密都是可逆的过程,只要使用正确的密钥,就可以还原原始数据。 签名 RSA算法可以用于数字签名,用于验证数据的完整性和真实性。签名过程是将数据使用私钥进行加密,验证过程是将签名使用公钥进行解密。
101 0
C# | 上位机开发新手指南(九)加密算法——RSA
|
4月前
|
算法 搜索推荐 安全
C# | 上位机开发新手指南(八)加密算法——AES
AES——这是在加密算法中相当重要的一种加密方式! 虽然这个世界上已经存在了非对称加密算法(比如RSA、ECC等),但是在对称加密算法中,AES的地位依然相当重要。与非对称加密算法不同,对称加密算法使用的是相同的密钥对数据进行加密和解密,因此其加密和解密速度更快,而且更加高效。而在对称加密算法中,AES是目前最安全、最可靠的加密算法之一,其加密强度和运行效率都非常高。因此,无论是在个人计算机、移动设备,还是在服务器和云计算等领域,AES都被广泛应用于数据的加密和解密过程中。
88 0
C# | 上位机开发新手指南(八)加密算法——AES
|
4月前
|
存储 算法 安全
C# | 上位机开发新手指南(七)加密算法
加密算法是信息安全领域中的重要技术之一,可以保护数据在传输、存储和处理过程中的安全性。 学习加密算法可以帮助我们更好地理解和应用其他相关技术。例如,数字证书、数字签名、安全协议等都与加密算法密切相关,掌握加密算法可以为我们理解和应用这些技术提供帮助。
54 0
C# | 上位机开发新手指南(七)加密算法