站点图标 江湖人士

C# 手搓版实现DES加密算法

C# 手搓版实现DES加密算法,.net 类库里面为各种加密算法(对称和非对称)封装了相应的类。数据加密标准 (DES) 是一种对称加密算法,它允许发送方和接收方使用相同的密钥来加密和解密数据。

DES 由 IBM 于 1975 年开发。由于其密钥大小为 56 位,块大小为 64 位,它被认为是一种不安全的算法。但是,它的继任者 Triple DES (3DES) 是安全的。TripleDES 在每个块上应用 DES 算法 3 次。这不,jexus作者前些天用C# 手搓版实现DES加密算法,需要的朋友自己复制。

C# 手搓版实现DES加密算法

DES加密调用方式和结果还是先上图吧。

C# 手搓版实现DES加密算法
using System.Text;

var text = "江湖人士(https://jhrs.com)是一个关注IT科技动态、技术经验分享、WordPress网站建设、wealthy affiliate 中文教程、国外最便宜域名、国外最便宜vps、网赚教程、国外网赚、网赚联盟、国外联盟营销、adsense 赚钱教程、养育小孩、游戏攻略、美女图片、热门美剧、以及分享赚被动收入的网站。";
var key = "key is:jhrs.com";
var des = new DES(Encoding.Default);
var desText = des.Encrypt(text, key);

Console.WriteLine("加密前的文本:{0}", text);
Console.WriteLine("*DES加密密钥:{0}", key);
Console.WriteLine("*DES加密结果:{0}", desText);
Console.WriteLine("解密后的文本:{0}", des.Decrypt(desText, key));

Console.WriteLine();
Console.WriteLine("press any key to exit");
Console.ReadKey(true);

C# 手搓版实现DES加密算法

C# 手搓版实现DES加密算法调用结果:

加密前的文本:江湖人士(https://jhrs.com)是一个关注IT科技动态、技术经验分享、WordPress网站建设、wealthy affiliate 中文教 程、国外最便宜域名、国外最便宜vps、网赚教程、国外网赚、网赚联盟、国外联盟营销、adsense 赚钱教程、养育小孩、游戏攻略、美 女图片、热门美剧、以及分享赚被动收入的网站。
*DES加密密钥:key is:jhrs.com
*DES加密结果:EDDCABF2E481C3E9E750F4C14D3810452382970F876322217A8183642420184327531CA8A7A32A0AA3D3E5262C3D4DC5A3C163D0E388F7C999F50EBD2BC0DDFA64391E7025AEDE8DFD7239A7B5995A800DB3FE6C28DBC2536C110873F2AD8741815E8CBF102C21211296729CEFE1EA219871117B2E266880CFB4A2508919152D2BFBD73081BE7AE3DF9B72D3E9F2E75C5CADD8FA9A8DF3C38ACC62A614C1A2D2B1AD8B1CAD6D859A5CADD8FA9A8DF3C30C3E79477B8A76E6A64535896C4352C6E34E94597AFD200CB09148C83735A4B456EC5F185A3736D16CB79A3AF464B71337BAB7292AF88B68A9846A8970AEF29EEF6317A9C039D18653B3C42631D9AF321340E09B4C292643217C56D7328F7E463B77CFA2F2A30E5C4469AEB20A19181FDF1EC1476F710CF8084E9DCB51D42E67B6584B878DC9CC6300F795C8ECAB8D4139E274EF0797419BC39CF7BD0914764710463E9A6B91CACF9897A8E94E7F1618707E9E40FFCAECBF4272FD452BD4EAC48387A976D22671B7
解密后的文本:江湖人士(https://jhrs.com)是一个关注IT科技动态、技术经验分享、WordPress网站建设、wealthy affiliate 中文教 程、国外最便宜域名、国外最便宜vps、网赚教程、国外网赚、网赚联盟、国外联盟营销、adsense 赚钱教程、养育小孩、游戏攻略、美 女图片、热门美剧、以及分享赚被动收入的网站。

press any key to exit

C# 手搓版实现DES加密算法

C# DES加密算法实现源码

/******************************************
 * C# 手搓版实现DES加密算法
 * ---------------------------------------
 * 作者:宇内流云(j66x@163.com),2022.6.22
 * 特注:请不要修改作者署名,做个重信重义的人!
 * ****************************************/

namespace System.Text
{
    using System.Runtime.CompilerServices;

    /// <summary>
    /// DES加解密类
    /// </summary>
    public sealed class DES
    {

        #region <定义>


        #region <枚举定义>

        enum DES_TYPE
        {
            /// <summary>
            /// 加密
            /// </summary>
            ENCRYPT,

            /// <summary>
            /// 解密
            /// </summary>
            DECRYPT
        };
        #endregion

        #region <表定义>

        static readonly byte[] ip_table = new byte[64]  {
            58, 50, 42, 34, 26, 18, 10, 2,
            60, 52, 44, 36, 28, 20, 12, 4,
            62, 54, 46, 38, 30, 22, 14, 6,
            64, 56, 48, 40, 32, 24, 16, 8,
            57, 49, 41, 33, 25, 17, 9, 1,
            59, 51, 43, 35, 27, 19, 11, 3,
            61, 53, 45, 37, 29, 21, 13, 5,
            63, 55, 47, 39, 31, 23, 15, 7
        };
        readonly static byte[] ipr_table = new byte[64] {
            40, 8, 48, 16, 56, 24, 64, 32,
            39, 7, 47, 15, 55, 23, 63, 31,
            38, 6, 46, 14, 54, 22, 62, 30,
            37, 5, 45, 13, 53, 21, 61, 29,
            36, 4, 44, 12, 52, 20, 60, 28,
            35, 3, 43, 11, 51, 19, 59, 27,
            34, 2, 42, 10, 50, 18, 58, 26,
            33, 1, 41, 9, 49, 17, 57, 25
        };
        readonly static byte[] e_table = new byte[48] {
            32, 1, 2, 3, 4, 5, 4, 5,
            6, 7, 8, 9, 8, 9, 10, 11,
            12, 13, 12, 13, 14, 15, 16, 17,
            16, 17, 18, 19, 20, 21, 20, 21,
            22, 23, 24, 25, 24, 25, 26, 27,
            28, 29, 28, 29, 30, 31, 32, 1
        };
        readonly static byte[] p_table = new byte[32] {
            16, 7, 20, 21, 29, 12, 28, 17,
            1, 15, 23, 26, 5, 18, 31, 10,
            2, 8, 24, 14, 32, 27, 3, 9,
            19, 13, 30, 6, 22, 11, 4, 25
        };
        readonly static byte[] pc1_table = new byte[56]{
            57,49,41,33,25,17,9,1,
            58,50,42,34,26,18,10,2,
            59,51,43,35,27,19,11,3,
            60,52,44,36,63,55,47,39,
            31,23,15,7,62,54,46,38,
            30,22,14,6,61,53,45,37,
            29,21,13,5,28,20,12,4
        };
        readonly static byte[] pc2_table = new byte[48]  {
            14,17,11,24,1,5,3,28,
            15,6,21,10,23,19,12,4,
            26,8,16,7,27,20,13,2,
            41,52,31,37,47,55,30,40,
            51,45,33,48,44,49,39,56,
            34,53,46,42,50,36,29,32
        };
        readonly static byte[] loop_table = new byte[16] {
            1, 1, 2, 2, 2, 2, 2, 2,
            1, 2, 2, 2, 2, 2, 2, 1
        };
        readonly static byte[,,] s_box = new byte[8, 4, 16] {
            //s1
            {
                { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
                { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
                { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
                { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
            },
            //s2
            {
                { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
                { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
                { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
                { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
            },
            //s3
            {
                { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
                { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
                { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
                { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
            },
            //s4
            {
                { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
                { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
                { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
                { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
            },
            //s5
            {
                { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
                { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
                { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
                { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
            },
            //s6
            {
                { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
                { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
                { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
                { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
            },
            //s7
            {
                { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
                { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
                { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
                { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
            },
            //s8
            {
                { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
                { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
                { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
                { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
            }
        };

        #endregion

        #region <变量/常量定义>

        /// <summary>
        /// 默认密钥C# 手搓版实现DES加密算法
        /// </summary>
        const string KEY_DEFAULT = "YUNEI.LIUYUN";

        /// <summary>
        /// 原文字符集
        /// </summary>
        private readonly Encoding _encoding = Encoding.Default;

        #endregion


        #endregion


        #region <内部方法>

        /// <summary>
        /// 加/解密(输入/输出缓冲都是8字节)--C# 手搓版实现DES加密算法
        /// </summary>
        /// <param name="lp_out">输出</param>
        /// <param name="lp_in">输入</param>
        /// <param name="type"></param>
        /// <param name="subkey"></param>
        /// <param name=""></param>
        static unsafe void DesRun(byte* lp_out, byte* lp_in, DES_TYPE type, byte* subkey)
        {
            var m = stackalloc byte[64];
            var tmp = stackalloc byte[32];
            var li = m + 0;
            var ri = m + 32;

            ByteToBit(m, lp_in, 64);
            Transform(m, m, ip_table, 64);

            if (type == DES_TYPE.ENCRYPT)
            {
                for (int i = 0; i < 16; i++)
                {
                    MemCopy(tmp, ri, 32);
                    FuncF(ri, subkey + (i * 48));
                    XOR(ri, li, 32);
                    MemCopy(li, tmp, 32);
                }
            }
            else
            {
                for (int i = 15; i >= 0; i--)
                {
                    MemCopy(tmp, li, 32);
                    FuncF(li, subkey + (i * 48));
                    XOR(li, ri, 32);
                    MemCopy(ri, tmp, 32);
                }
            }

            Transform(m, m, ipr_table, 64);
            BitToByte(lp_out, m, 64);
        }

        /// <summary>
        /// 设置子密钥--C# 手搓版实现DES加密算法
        /// </summary>
        /// <param name="key"></param>
        /// <param name="subkey_out"></param>
        static unsafe void DesSetKey(string key, byte* subkey_out)
        {

            if (string.IsNullOrEmpty(key)) key = KEY_DEFAULT;
            var des_key = stackalloc byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
            for (int ii = 0; ii < key.Length; ii++)
            { des_key[ii % 8] = (byte)((des_key[ii % 8] + key[ii]) % 256); }

            var k = stackalloc byte[64];
            var kl = k + 0;
            var kr = k + 28;
            ByteToBit(k, des_key, 64);
            Transform(k, k, pc1_table, 56);
            for (int i = 0; i < 16; i++)
            {
                Rotatel(kl, 28, loop_table[i]);
                Rotatel(kr, 28, loop_table[i]);
                Transform(subkey_out + (i * 48), k, pc2_table, 48);
            }
        }



        static unsafe void FuncF(byte* lpin, byte* lpki)
        {
            var mr = stackalloc byte[48];
            Transform(mr, lpin, e_table, 48);
            XOR(mr, lpki, 48);
            FuncS(lpin, mr);
            Transform(lpin, lpin, p_table, 32);
        }


        static unsafe void FuncS(byte* lp_out, byte* lp_in)
        {
            for (int i = 0, j = 0, k = 0; i < 8; i++, lp_in += 6, lp_out += 4)
            {
                j = (lp_in[0] << 1) + lp_in[5];
                k = (lp_in[1] << 3) + (lp_in[2] << 2) + (lp_in[3] << 1) + lp_in[4];

                //bytetobit(lp_out, &s_box[i, j, k], 4);
                fixed (byte* p = s_box)//s_box[8,4,16]
                {
                    var pp = p + (i * 4 * 16) + (j * 16) + k;
                    ByteToBit(lp_out, pp, 4);
                }
            }
        }


        static unsafe void Transform(byte* out_bit, byte* in_bit, byte[] table, int len)
        {
            var tmp = stackalloc byte[256];
            for (var i = 0; i < len; i++)
            {
                tmp[i] = in_bit[table “” not found /]
- 1]; } MemCopy(out_bit, tmp, len); } unsafe static void Rotatel(byte* lpin, int len, int loop) { var tmp = stackalloc byte[256]; MemCopy(tmp, lpin, loop); MemCopy(lpin, lpin + loop, len - loop); MemCopy(lpin + len - loop, tmp, loop); } #region <辅助函数> /// <summary> /// 将字节转换为位--C# 手搓版实现DES加密算法 /// </summary> /// <param name="bit_out"></param> /// <param name="byt_in"></param> /// <param name="bits">输出的长度(位长度)</param> [MethodImpl(MethodImplOptions.AggressiveInlining)] unsafe static void ByteToBit(byte* bit_out, byte* byt_in, int bits) { for (int i = 0; i < bits; i++) { bit_out[i] = (byte)((byt_in[i / 8] >> (i % 8)) & 0x01); } } /// <summary> /// 将位转换为字节 /// </summary> /// <param name="lp_out"></param> /// <param name="lp_in"></param> /// <param name="bits">位的长度</param> unsafe static void BitToByte(byte* lp_out, byte* lp_in, int bits) { MemZero(lp_out, (bits + 7) / 8); for (int i = 0; i < bits; i++) { lp_out[i / 8] |= (byte)((lp_in[i] & 0x01) << (i % 8)); } } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] static unsafe void XOR(byte* ina, byte* inb, int len) { for (int i = 0; i < len; i++) { ina[i] ^= (byte)(inb[i] & 0x01); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] unsafe static void MemCopy(byte* dest, byte* src, int len) { for (int i = 0; i < len; i++) dest[i] = src[i]; } /// <summary> /// 用0填充指定的缓冲区,C# 手搓版实现DES加密算法 /// </summary> /// <param name="buffer">缓冲区</param> /// <param name="len">填充长度</param> [MethodImpl(MethodImplOptions.AggressiveInlining)] unsafe static void MemZero(byte* buffer, int len) { for (var i = 0; i < len; i++) buffer[i] = 0; } #endregion #endregion #region <构造函数> /// <summary> /// 一个以系统默认字符集作编确码字符集的实例 /// </summary> public DES() : this(Encoding.Default) { } /// <summary> /// 一个以指定字符集作编解码字符集的实例 /// </summary> /// <param name="encoding"></param> public DES(Encoding encoding) { _encoding = encoding; } #endregion #region <公共方法或属性,C# 手搓版实现DES加密算法> /// <summary> /// 加密--C# 手搓版实现DES加密算法 /// </summary> /// <param name="text">待加密的原文本</param> /// <param name="key">密钥</param> /// <returns>DES加密文本</returns> public unsafe string Encrypt(string text, string key = "") { if (string.IsNullOrEmpty(text)) return text; var str_in = stackalloc byte[8]; var str_out = stackalloc byte[8]; var subkey = stackalloc byte[16 * 48]; //子密钥 DesSetKey(key, subkey); var byt_text = _encoding.GetBytes(text); int text_len = byt_text.Length; var byt_result = new byte[(text_len + 7) / 8 * 16]; int count = (text_len + 7) / 8; for (int kk = 0; kk < count; kk++) { for (int ii = 0; ii < 8; ii++) { if (kk * 8 + ii < text_len) str_in[ii] = byt_text[kk * 8 + ii]; else str_in[ii] = 0; } DesRun(str_out, str_in, DES_TYPE.ENCRYPT, subkey); for (int ii = 0; ii < 8; ii++) { var value = str_out[ii]; byt_result[kk * 16 + 2 * ii] = (byte)(value / 16 < 10 ? value / 16 + '0' : value / 16 - 10 + 'A'); byt_result[kk * 16 + 2 * ii + 1] = (byte)(value % 16 < 10 ? value % 16 + '0' : value % 16 - 10 + 'A'); } } return Encoding.ASCII.GetString(byt_result); } /// <summary> /// 解密,C# 手搓版实现DES加密算法 /// </summary> /// <param name="des">DES加密文本</param> /// <param name="key">密钥</param> /// <returns>解密后的原文本</returns> public unsafe string Decrypt(string des, string key = "") { if (string.IsNullOrEmpty(des)) return des; var byt_text = Encoding.ASCII.GetBytes(des); //把16进制表示的text字符串转换为正常字符。 int text_len = byt_text.Length; var text_str = new byte[text_len / 2]; if (text_len % 16 != 0) return ""; //DES加密字符串的长度必须是16的倍数 for (int ii = 0; ii < text_len; ii += 2) { var ch1 = byt_text[ii]; var ch2 = byt_text[ii + 1]; if (!(ch1 >= '0' && ch1 <= '9' || ch1 >= 'A' && ch1 <= 'F')) return ""; if (!(ch2 >= '0' && ch2 <= '9' || ch2 >= 'A' && ch2 <= 'F')) return ""; var k1 = ch1 <= '9' ? ch1 - '0' : ch1 - 'A' + 10; var k2 = ch2 <= '9' ? ch2 - '0' : ch2 - 'A' + 10; var kk = (byte)(k1 * 16 + k2); text_str[ii / 2] = kk; } var str_in = stackalloc byte[8]; var str_out = stackalloc byte[8]; var subkey = stackalloc byte[16 * 48]; DesSetKey(key, subkey); text_len = text_str.Length; var byt_result = new byte[text_len]; int len = 0; for (int kk = 0; kk < text_len / 8; kk++) { for (int ii = 0; ii < 8; ii++) { if (kk * 8 + ii < text_len) str_in[ii] = text_str[kk * 8 + ii]; else str_in[ii] = 0; } DesRun(str_out, str_in, DES_TYPE.DECRYPT, subkey); for (int ii = 0; ii < 8; ii++) { byt_result[kk * 8 + ii] = str_out[ii]; if (str_out[ii] != 0) len = kk * 8 + ii + 1; } } return _encoding.GetString(byt_result, 0, len); } /// <summary> /// 当前实例在编解码过程中使用的字符集,C# 手搓版实现DES加密算法 /// </summary> public Encoding Encoding { get { return _encoding; } } #endregion } }

C# 手搓版实现DES加密算法

C# 手搓版实现DES加密算法
退出移动版