RC6加密解密算法C#实现源码!
本人写的C#类,该算法完善了《朱明海--维普资讯网--对称加解密算法RC6的C#实现》未完善的源码,以供大家学习!
该RC6加密解密算法如有错误,请大家批评指正。
更多内容请参考:本人写的 C#_RC6加密解密方法 http://download.csdn.net/source/2864830
#region
using System;
using System.Collections.Generic;
using System.Text;
namespace WindowsApplication1
{
class RC6
{
/// <summary>
/// 对称加解密算法RC6的C#实现
/// 公开维普网_朱明海先生未公布的源码
/// 程序完善设计者:四川威远_老耙子 先生
/// 2010-11-28
/// 本程序只提供了明文长度32的算法。
/// 如有需要,请与本人联系。
/// Mail:chscwyyg@163.com 电话:0832-8229211
/// </summary>
private string m_sEncryptionKey; //密码方法通过KEY属性返回值
public string m_sCryptedText; //加密解密字符串返回值
private int m_nChipherlen; //密码字节数,控制加密最低为128,最好256,间192,有三种选择种16,24,32
private const int m_nWord = 32;
private const int r = 20;
private const int c = 4;
private uint[] m_nKeyExpandBox; //系统密钥数组
uint[] n_WordBox; //用户私有密钥
public Encoding Enc_default = Encoding.Unicode;
/// <summary>
/// 左位移运算函数
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="w"></param>
/// <returns></returns>
///
public uint ROTL(uint x, uint y, int w)
{ return ((x << (int)(y & (0xFF))) | (x >> (int)(w - (y & (0xFF))))); }//或:return ((x << (int)(y & (w-1))) | (x >> (int)(w - (y & (w-1)))));
/// <summary>
/// 右位移运算函数
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="w"></param>
/// <returns></returns>
public uint ROTR(uint x, uint y, int w)
{ return ((x >> (int)(y & (0xFF))) | (x << (int)(w - (y & (0xFF))))); }//或:return ((x >> (int)(y & (w-1))) | (x << (int)(w - (y & (w-1)))));
/// <summary>
/// 构造函数
/// </summary>
public RC6()
{
IV = 16; //如果用户没有设置加密方式系统默认为128位加密
// IV返回m_nChipherlen
m_nKeyExpandBox = new uint[8 * m_nChipherlen]; //密钥数组大小为加IV*8
}
/// <summary>
/// 构造函数可输入加密向量
/// </summary>
/// <param name="iv"></param>
public RC6(int iv)
{
IV = iv; //返顺 m_nChipherlen
this.m_nKeyExpandBox = new uint[8 * m_nChipherlen];
}
/// <summary>
/// 定义一个属性,通过属性输入用户密钥并返回
/// 存储到m_sEncryptionKey
/// </summary>
public string KEY
{
get { return this.m_sEncryptionKey; }
set { this.m_sEncryptionKey = value; }
}
/// <summary>
/// 加密向量选择
/// 128方式IV=16
/// 192方法IV=24
/// 256方法IV=32
/// </summary>
public int IV
{
get { return m_nChipherlen; }
set { m_nChipherlen = value; }
}
/// <summary>
/// 加密向量验证函数
/// 有错误返回最小或最大的向量设置
/// </summary>
/// <returns></returns>
public int _IV()
{
if (m_nChipherlen < 16) m_nChipherlen = 16;
if (m_nChipherlen > 32) m_nChipherlen = 32;
return m_nChipherlen;
}
/// <summary>
/// string类型Unicode字符集转为字节流char[];
/// </summary>
/// <returns></returns>
private char[] String_Unicode()
{
string prssword = this.m_sEncryptionKey;
prssword = (prssword.Length % m_nChipherlen != 0 ? prssword.PadRight(prssword.Length + (m_nChipherlen - (prssword.Length % m_nChipherlen)), '/0') : prssword);
byte[] asciiBytes = Encoding.Convert(Encoding.Unicode, Encoding.ASCII, Encoding.Unicode.GetBytes(prssword));
char[] asciiChars = new char[Encoding.ASCII.GetCharCount(asciiBytes, 0, asciiBytes.Length)]; //等价=====char[] asciiChars = new char[asciiBytes.Length];
Encoding.ASCII.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0);
return asciiChars;
}
/// <summary>
/// 初始化函数用户密钥
/// 通过KeySteup函数扩展并混合密钥
/// </summary>
///
private void KeySteup()
{
uint P32 = 0xb7e15163;
uint Q32 = 0x9e3779b9;
uint A, B;
A = B = 0;
int i, j;
i = j = 0;
char[] key = String_Unicode(); 密码类型转换,String型转换为char[],下面String_Unicode()函数返回值
n_WordBox = new uint[m_nChipherlen/4]; //选择 16 or 24 or 32 128,192,256加密方式,4,6,8
uint temp;
//密钥类型转换 string类型转换为uint
for (j = 0; j < m_nChipherlen; j++) //asciiChars[j]作0xFF运算,循环左移,如果 m_nChipherlen=32,第一轮不移位字节占位0-7,第二轮左移8位字节占位8-15, 第三轮位移16位,字节占16-23,
{ //第四轮位移24位字节占位24-31.第四轮生成一个uint,共循环m_nChipherlen次生成m_nChipherlen/4个Uint, 16只生成4个,24生成6个,32生成8个,每个uint点32位,
// 所以加密的密节数==16时,4*32=加密128位,24时==6*32加密192位,32时==8*32加密256位,这里实现加密方式
temp = (uint)(key[j] & 0xFF) << (8 * (j % 4));
n_WordBox[j / 4] += (uint)temp; //循环四次生成一个uint
/* ========================================================说明位移运算方法===================================================================//
* 比方:a=97为01100001,0移位Convert.ToString(97, 2).PadLeft(8, '0'),
* b=98为01100010,左移8后变成占位0110001000000000=25088;
* c=99为01100011,左移16位变成占位011000110000000000000000=6488064
* d=100为01100100,左移24变成占位01100100000000000000000000000000=1677721600
* 以上abcd左移运算后是以下情况
* abcd相加后变成了一个Uint数据占32字节等于Convert.ToString(100, 2).PadLeft(8, '0') + Convert.ToString(99, 2).PadLeft(8, '0') +
* Convert.ToString(98, 2).PadLeft(8, '0') + Convert.ToString(97, 2).PadLeft(8, '0');
* a+b+c+d=1684234849,其字节为01100100011000110110001001100001;uint value=1684234849请验证下。
* uint转换为字节 string x=Convert.ToString(uint value,2);
*/
}
//密钥扩展 m_nChipherLen=32 or 24 or 16
this.m_nKeyExpandBox[0] = P32; //扩展密钥初始化,0位置赋值P32
for (j = 1; j < 2 * m_nChipherlen + 4; j++) //m_nChipherlen是加密向量,反应加密方式128,192,256三种
{ this.m_nKeyExpandBox[j] = m_nKeyExpandBox[j - 1] + Q32; }
int k = 3 * Math.Max(n_WordBox.Length, 2 * m_nChipherlen + 4);
for (j = 0, i = 0; k > 0; k--)
{
A = ROTL(m_nKeyExpandBox[i] + A + B, 3, m_nWord); //混合密钥
m_nKeyExpandBox[i] = (byte)A;
B += A;
B = ROTL(n_WordBox[j] + A + B, A + B, m_nWord); //m_nKeyExpandBox[ii]的值混合到用户密钥中
n_WordBox[j] = B; //这里是仍然是uint,生成新用户密码,32位值。提取见上面方法 [*** 1]
i = (i + 1) % (2 * m_nChipherlen + 4); //取模运算确保对应 m_nKeyExpandBox和 n_WordBox数组不越界
j = (j + 1) % n_WordBox.Length; //n_WordBox.Length 分别代表 4,6,8
}
}
//
/// <summary>
/// 加密函数
/// </summary>
/// <param name="str">加密的明文</param>
/// <param name="prssword">返回的密文</param>
/// <returns></returns>
public string Encrypt(string str, string prssword)
{
str = (str.Length % 32 != 0 ? str.PadRight(str.Length + (32 - (str.Length % 32)), '/0') : str);//验证明文长度不能小开32,不足补空字符串
KEY = prssword; //Key属性返回m_sEncryptionKey方法
KeySteup(); //初始化
uint A, B, C, D, T, U, temp; T = U = 0; //4个32位循环赋值的uint(A,B,C,D)
A = B = C = D = 0;
temp = 0;
byte[] input = Encoding.Unicode.GetBytes(str); // 输入的明文this.m_slnClearText;明文string为Unicode字符集,每个输入字符均为两字节16位
//以Unicode转换Byte是byte[1]奇数值为0,偶数值为0,2,4,6等等为输入的字符十进制值,所以低位值才是要加密的值,高位不管它,因为它为0.
char[] chars = new char[Encoding.ASCII.GetCharCount(input, 0, input.Length)];
Encoding.ASCII.GetChars(input, 0, input.Length, chars, 0);
byte[] output = new Byte[input.Length];
// 加密的字符串不只128个字符情况该如何, 这需要定义byte多维数据才能实现
for (int k = 0; k < 4; k++) /* 输入明文要求为ASCII,将字节低位进行0xFF运算左移8*k位转换input(uint) */
{
A += (uint)(input[2 * k] & 0xFF) << (8 * k); //第一个元素不移位,填充uint0-7位,第二个左移8位填充8-15,第三个左移16位填充16-23位,第四个左移24位填充24-31位,这样组成一个uint
B += (uint)(input[2 * k + 8] & 0xFF) << (8 * k); //第五个位元素填充uint32-39位,六个填充40-47位,七个填充48-55位,八个填充56-63位
C += (uint)(input[2 * k + 16] & 0xFF) << (8 * k); //第九个位元素填充uint64-71位,十个填充72-79位,十一个填充80-87位,十二个填充88-95位
D += (uint)(input[2 * k + 24] & 0xFF) << (8 * k); //第十三个位元素填充uint96-103位,十四个填充104-111位,十五个填充112-119位,十六个填充120-127位
}
/* 扩展密钥数组n_LocExpandBox和A,B,C,D进行基本加密
*/
//A,B,C,D变量循环赋值,第一次A,B,C,D第二次B,C,D,A,第三次C,D,A,B,以此类推,共循环m_nChipherlen-1次。
B += m_nKeyExpandBox[0];
D += m_nKeyExpandBox[1];
for (int i = 1; i <= m_nChipherlen; i++) //左移计算并位置换位,矩阵运算
{
U = ROTL(D * (2 * D + 1), 5, m_nWord); //左移5位,这里其实m_nWord没有多少实用价值,因为本类未使用return ((x << (int)(y & (w-1))) | (x >> (int)(w - (y & (w-1)))))
T = ROTL(B * (2 * B + 1), 5, m_nWord);
A = ROTL(A ^ T, U, m_nWord) + m_nKeyExpandBox[2 * i];
C = ROTL(C ^ U, T, m_nWord) + m_nKeyExpandBox[2 * i + 1];
temp = A; //中间变量temp的值为A
A = B; //B的值赋值给A,就是B的位置移动到了A
B = C; //C的值赋值给B,就是C的位置移动到了B
C = D; //D的值赋值给C,就是D的位置移动到了C
D = temp; //A的值赋值给D,就是A的位置移动到了D
}
uint[] put = new uint[4];
A += m_nKeyExpandBox[2 * r + 2];
C += m_nKeyExpandBox[2 * r + 3];
put[0] = A;
put[1] = B;
put[2] = C;
put[3] = D;
//转换A,B,C,D为一个字节组output,并进而转换为string型m_sCrytedText,下面是第一步的逆操作.
for (int k = 0; k < 4; k++)
{
output[2 * k] = (byte)((put[0] >> 8 * k) & 0xFF);
output[2 * k + 8] = (byte)((put[1] >> 8 * k) & 0xFF);
output[2 * k + 16] = (byte)((put[2] >> 8 * k) & 0xFF);
output[2 * k + 24] = (byte)((put[3] >> 8 * k) & 0xFF);
}
char[] outarrchar = new char[output.Length];
Encoding.Unicode.GetChars(output, 0, output.Length, outarrchar, 0);
this.m_sCryptedText = new string(outarrchar, 0, outarrchar.Length);
byte[] Output1 = Enc_default.GetBytes(this.m_sCryptedText);
//this.m_sEncryptionKey = "";
return m_sCryptedText;
}
/// <summary>
/// 解密函数
/// </summary>
/// <param name="str">解密的密文</param>
/// <param name="prssword">解密后的明文</param>
/// <returns></returns>
public string Decrypt(string str, string prssword)
{
str = (str.Length % 32 != 0 ? str.PadRight(str.Length + (32 - (str.Length % 32)), '/0') : str);//验证密文长度不能小开32,不足补空字符串
KEY = prssword; //Key属性返回m_sEncryptionKey方法
KeySteup(); //初始化
uint A, B, C, D, T, U, temp; T = U = 0; //4个32位循环赋值的uint(A,B,C,D)
A = B = C = D = 0;
temp = 0;
byte[] input = Enc_default.GetBytes(str); // 输入的密文this.m_slnClearText;明文string为Unicode字符集,每个输入字符均为两字节16位
byte[] output = new Byte[input.Length];
for (int k = 0; k < 4; k++)
{
A += ((uint)input[2 * k] & 0xFF) << (8 * k);
B += ((uint)input[2 * k + 8] & 0xFF) << (8 * k);
C += ((uint)input[2 * k + 16] & 0xFF) << (8 * k);
D += ((uint)input[2 * k + 24] & 0xFF) << (8 * k);
}
C -= m_nKeyExpandBox[2 * r + 3];
A -= m_nKeyExpandBox[2 * r + 2];
for (int i = 1; i <= m_nChipherlen; i++)
{
temp = D;
D = C;
C = B;
B = A;
A = temp;
U = ROTL(D * (2 * D + 1), 5, m_nWord);
T = ROTL(B * (2 * B + 1), 5, m_nWord);
C = ROTR(C - m_nKeyExpandBox[2 * (m_nChipherlen - i) + 3], T, m_nWord) ^ U;
A = ROTR(A - m_nKeyExpandBox[2 * (m_nChipherlen - i) + 2], U, m_nWord) ^ T;
}
D -= m_nKeyExpandBox[1];
B -= m_nKeyExpandBox[0];
//转换A,B,C,D为一个字节组output,并进而转换为string型m_sCrytedText,下面是第一步的逆操作.
for (int k = 0; k < 4; k++)
{
output[2 * k] = (byte)((A >> (8 * k)) & 0xFF);
output[2 * k + 8] = (byte)((B >> (8 * k)) & 0xFF);
output[2 * k + 16] = (byte)((C >> (8 * k)) & 0xFF);
output[2 * k + 24] = (byte)((D >> (8 * k)) & 0xFF);
}
char[] outarrchar = new char[Enc_default.GetCharCount(output, 0, output.Length)];
Enc_default.GetChars(output, 0, output.Length, outarrchar, 0);
this.m_sCryptedText = new string(outarrchar, 0, outarrchar.Length);
byte[] Output1 = Enc_default.GetBytes(this.m_sCryptedText);
//this.m_sEncryptionKey = "";
return m_sCryptedText;
}
}
}
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
private int round;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (this.textBox1.Text == "") { MessageBox.Show("请输入加密的明文"); this.textBox1.Focus(); return; }
if (this.textBox3.Text == "") { MessageBox.Show("请输入加密的密钥"); this.textBox3.Focus(); return; }
RC6 RC = new RC6(round);
//如果手动输入加密向量RC.IV = -1;请使用RC._IV():函数进行验证。
textBox2.Text = RC.Encrypt(this.textBox1.Text, this.textBox3.Text);
comboBox1.Enabled = false; comboBox1.ForeColor = System.Drawing.SystemColors.WindowText;
textBox2.Enabled = false; textBox2.ForeColor = System.Drawing.SystemColors.WindowText;
textBox3.Enabled = false; textBox3.ForeColor = System.Drawing.SystemColors.WindowText;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string str = this.comboBox1.Text;
switch (str)
{
case "128位加密": round = 16; break;
case "192位加密": round = 24; break;
case "256位加密": round = 32; break;
default: break;
}
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.SelectedIndex = 0;
}
private void button2_Click(object sender, EventArgs e)
{
RC6 RC = new RC6(round);
this.label6.Text = RC.Decrypt(this.textBox2.Text, this.textBox3.Text);
comboBox1.Enabled = true; comboBox1.ForeColor = System.Drawing.SystemColors.WindowText;
textBox2.Enabled = true; textBox2.ForeColor = System.Drawing.SystemColors.WindowText;
textBox3.Enabled = true; textBox3.ForeColor = System.Drawing.SystemColors.WindowText;
}
}
}
实现加解密效果图:128位加解密
192位加解密:
256位加解密:
RC6加密解密算法C#实现源码!相关推荐
- 【图像加密】 Logistic混沌+Arnold置乱图像加密解密【含Matlab源码 1281期】
⛄一.混沌图像加密与解密简介 混沌系统图像加密解密理论部分参考链接: 基于混沌系统的图像加密算法设计与应用 ⛄二.Arnold置乱图像加密解密简介 0 前言 网络已经成为我们传递信息的主要平台, 为我 ...
- 【图像加密】基于matlab GUI正交拉丁方置乱+混沌图像加密解密【含Matlab源码 636期】
⛄一.正交拉丁方置乱及混沌系统简介 0 引言 随着通讯技术的飞速发展, 越来越多的领域需要传送数字图像信号, 因此信息的传送安全问题显得越来越重要.通常应用于数字图像通信的两种保护技术为:数字水印技术 ...
- 还愁不能解密MD5值?简单代码就能实现md5加密解密,内附源码,亲测可用
众所周知,md5本身是不可逆的,但我们可以使用以下代码中提供的接口进行解密啊!我试了下成功率是非常的高!8位以内的纯数字的md5值都可以解密. php代码 <?php $MiWen = &quo ...
- python:实现DES和3DES加解密算法(附完整源码)
python:实现DES和3DES加解密算法 import sys _pythonMajorVersion = sys.version_info[0]# Modes of crypting / cyp ...
- JAVA:实现XXTea加解密算法(附完整源码)
JAVA:实现XXTea加解密算法 public class XXTEAprivate XXTEA() {}public static byte[] encrypt(byte[] data, byte
- C#:实现SM2加解密算法(附完整源码)
C#:实现SM2加解密算法 public class SM2CryptoUtil {public SM2CryptoUtil(byte[] pubkey, byte[] privkey, Mode m ...
- 基于新唐M0的XXTEA加密解密算法源码
源:基于新唐M0的XXTEA加密解密算法源码 /*--------------------------------------------------------------------------- ...
- 【Matlab图像加密】正交拉丁方置乱算法图像加解密【含GUI源码 182期】
一.代码运行视频(哔哩哔哩) [Matlab图像加密]正交拉丁方置乱算法图像加解密[含GUI源码 182期] 二.matlab版本及参考文献 一.代码运行视频(哔哩哔哩) [Matlab图像处理]自动 ...
- 【安全算法之base64】base64加解密的C语言源码实现
最近,有项目中需要用到base64的加解密,所以用C语言实现了一遍,测试效果还不错,代码量和RAM消耗都比较低,可以提供给大家参考下. #include <stdbool.h> #incl ...
最新文章
- 一篇文章告诉你如何成为数据科学家
- Tortoise SVN 版本控制常用操作汇总(show log)
- 李宏毅机器学习(七)GPT的野望
- php 取得文件行数,PHP获取文件行数的方法
- GSAP JS基础教程--动画的控制及事件
- qscoj:喵哈哈村的烧烤店(阶梯博弈)
- mysql 再查询结果的基础上查询(子查询)
- 小米高通系列清串号打开写号端口工具_高通刷机工具最新版下载(Qualcomm Product Support Tool) v2.7 官方版_数码资源网...
- 工业视觉 五 频闪及抑制频闪
- PDF文件如何编辑?这两种方法是我一直在用的
- java计算机毕业设计爱心公益网站设计与制作源码+数据库+系统+lw文档+部署
- 迅为3A5000_7A2000开发板龙芯国产处理器LoongArch架构
- 配置HTTPS,和HTTPS转HTTP
- 如Java8的LocalDate与Date相互转换、ZonedDateTime等常用操作包含多个使用示例、Java8时区ZoneId的使用方法、Java8时间字符串解析成类
- 【目标跟踪】帧差法结合卡尔曼滤波行人姿态识别【含GUI Matlab源码 1127期】
- matlab白化权函数,《灰色系统、白化规律和白化权函数.pdf》-支持高清全文免费浏览-max文档...
- 发那科机器人没有码垛指令_FANUC机器人码垛教程
- RHCS+Conga+iSCSI+CLVM+GFS实现Web服务的共享存储HA集群
- 值得期待!中兴新支点4G多卡聚合技术将融合到新型导播机
- 内核模式代码签名走查(一)
热门文章
- python编程软件免费吗_Python Mac下载-Python for Mac(Python编程工具) v3.10.0a2免费版
- 程序员的职业素养(一)
- 中国磷酸市场应用现状规模与需求前景预测报告2022-2028年
- 京东登录页面html代码_2019双十一天猫/京东自动获取喵币/金币方法
- FPGA专题-相位累加器(DDS)
- 新学问教育php,神墨教师的教育梦——让梦想与爱同行
- 用python编写一个猜年龄的小程序-知道了这个,你也能写出 Python 趣味小程序
- 《Ext JS 6.2实战》节选——迁移管理模版
- 初等行变换、初等列变换
- c++算法:四数之和---固定两数,用夹逼法