C# 手搓版实现DES加密算法,.net 类库里面为各种加密算法(对称和非对称)封装了相应的类。数据加密标准 (DES) 是一种对称加密算法,它允许发送方和接收方使用相同的密钥来加密和解密数据。
DES 由 IBM 于 1975 年开发。由于其密钥大小为 56 位,块大小为 64 位,它被认为是一种不安全的算法。但是,它的继任者 Triple DES (3DES) 是安全的。TripleDES 在每个块上应用 DES 算法 3 次。这不,jexus作者前些天用C# 手搓版实现DES加密算法,需要的朋友自己复制。
C# 手搓版实现DES加密算法
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加密算法