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加密算法
