📄 form1.cs
字号:
this.label8.Size = new System.Drawing.Size(296, 32);
this.label8.TabIndex = 3;
this.label8.Text = "DES分组解密=》带有时间戳明文=》MD5摘要生成";
//
// label7
//
this.label7.Location = new System.Drawing.Point(72, 128);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(296, 24);
this.label7.TabIndex = 4;
this.label7.Text = "发送者公钥得到明文摘要";
//
// label9
//
this.label9.Location = new System.Drawing.Point(344, 112);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(256, 24);
this.label9.TabIndex = 5;
this.label9.Text = "摘要对比 =》提取验证时间戳=》得到明文";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(640, 438);
this.Controls.Add(this.CreateXmlKeys);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.richbox);
this.Name = "Form1";
this.Text = "Form1";
this.groupBox1.ResumeLayout(false);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.groupBox4.ResumeLayout(false);
this.groupBox3.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.tabPage3.ResumeLayout(false);
this.groupBox5.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
byte [] fileContents;//=null;//储存原始的明文数据
//打开文件
private void OpenFileBtn_Click(object sender, System.EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
open.Title = "请打开你要产生摘要的文件:";
open.Filter = "All File (*.*)|*.*";
if(open.ShowDialog()==DialogResult.OK)
{
FileName.Text = open.FileName ;
richbox.AppendText("\n你选择了要进行散列的文件:" + FileName.Text);
}
else
{
return ;
}
}
private void SendFileToDTS_Click(object sender, System.EventArgs e)
{
try
{
//读取文件内容到一数组里
FileStream fs = new FileStream(FileName.Text,FileMode.Open,FileAccess.Read);
byte [] ifileContent = new byte[(int)fs.Length];
fs.Read(ifileContent,0,(int)fs.Length);
fs.Close(); //读取到数组中去
fileContents = ifileContent ;
}
catch
{
richbox.AppendText("\n读取文件失败,请仔细查找原因!");
}
byte [] HashValue = null;
try
{//产生文件散列
HashValue = ShareClass.HashFile(0,FileName.Text);
richbox.AppendText("\n已经产生了文件散列 :\n 散列长度:"+ HashValue.Length.ToString() +"\n散列:\n"+Convert.ToBase64String(HashValue,0,HashValue.Length)/* System.Text.Encoding.Default.GetString(HashValue)*/);
}
catch
{
richbox.AppendText("\n计算文件散列失败!");
}
//DTS获取收到文件时间
byte [] TimeNow = ShareClass.GetTimeNow();
richbox.AppendText("\n时间数组长度--TimeNow: "+ TimeNow.Length.ToString());
//把时间加进散列中
byte[]HashAndTime = ShareClass.CombinBytes(TimeNow,HashValue);
richbox.AppendText("\n接受到数据时间: " + System.Text.Encoding.Default.GetString(TimeNow) + " \n已经加进到文件摘要中!");
//签名签名数组
byte [] signHash = ShareClass.Sinature(ShareClass.OpenFile("DTSPrivateKey.txt"),HashAndTime );
richbox.AppendText("\n已经为文件签名!\n签名长度--signHash:" + signHash.Length.ToString());
//合并成DTS时间戳格式数组
byte [] combinData = ShareClass.CombinBytes(signHash,HashAndTime);
try
{
fileContents = ShareClass.CombinBytes(combinData,fileContents); //加进时间戳
richbox.AppendText("\n现已把时间戳添加到文件中去!");
}
catch
{richbox.AppendText("\n添加时间戳失败!");}
}
//错误的原因:不正确的数组长度。
private void StartStepsBtn_Click(object sender, System.EventArgs e)
{
//产生随机的密码和向量
byte[]Key =ShareClass.RandomKey(0);
byte[]IV =ShareClass.RandomIV(0);
richbox.AppendText("\n产生了随机密码:KEY 和向量:IV!\nKey and IV Size: " + Key.Length.ToString() +" "+IV.Length.ToString());
//对随机密码和向量进行签名和加密
byte [] KeyAndIV = ShareClass.CombinBytes(IV,Key);//这里把Key和IV合并一起
richbox.AppendText("\nKeyAdnIV Size : "+KeyAndIV.Length.ToString() );
//把整个密码参数签名
byte [] Signature = ShareClass.Sinature(ShareClass.OpenFile("A_PrivateKey.txt"),KeyAndIV);
richbox.AppendText("\n签名整个密码参数-KeyAndIV : Signature Size: "+ Signature.Length.ToString());
//合并密码参数和签名
byte [] KeyAndSignature = ShareClass.CombinBytes(Signature,KeyAndIV);
//使用B的公钥加密密码和密码签名数组
byte [] RsaEncryptData = ShareClass.RsaEncrypt(ShareClass.OpenFile("B_PublicKey.txt"),KeyAndSignature);//Signature); //对已经签名的数据进行非对称加密处理
richbox.AppendText("\n对已经签名的密码数据进行非对称加密处理--信封处理 \n数字信封的长度: RsaEncryptData : " + RsaEncryptData.Length.ToString());
// ShareClass.WriteFile(FileName.Text+".enc",RsaEncryptData); //写进文件:数字信封
//对称加密已经加进时间戳的明文
// ShareClass.EncryptFile(0,FileName.Text,FileName.Text+".enc",Key,IV); //把对文件加密后的的数据写进文件
//int choice,string filename,byte[]Key,byte[]IV
//对含时间戳的明文进行DES分组加密
byte [] EncryptionDate = ShareClass.EncryptFile(0,fileContents,Key,IV);//加密加时间戳的明文
richbox.AppendText("\n加密已经加进时间戳的明文,使用随机产生的密码和向量:KEY、IV ");
richbox.AppendText("密文长度:EncryptionDate: "+EncryptionDate.Length.ToString());
//对含时间戳的明文进行摘要
byte [] HashFile = ShareClass.HashData(0,fileContents);//HashFile(0,FileName.Text); //计算摘要 //////////////////////////////////////////////
richbox.AppendText("\n计算已经加进时间戳的明文摘要,摘要长度:HashFile :" + HashFile.Length.ToString());
//为摘要签名
byte [] SignatureData = ShareClass.Sinature(ShareClass.OpenFile("A_PrivateKey.txt"),HashFile);
richbox.AppendText("\n对该摘要进行签名,签名长度:SignatureData:" +SignatureData.Length.ToString());
byte [] CombinData =ShareClass.CombinBytes(SignatureData,HashFile); //把摘要和签名合并一起
richbox.AppendText("\n开始合并这三部分......\n长度:CombinData: "+ CombinData.Length.ToString());
//把加密结果写进文件//要注意写入的顺序!
FileStream FS = new FileStream(FileName.Text+".enc",FileMode.Create,FileAccess.Write);
FS.Write( RsaEncryptData,0,RsaEncryptData.Length );
FS.Write( EncryptionDate,0,EncryptionDate.Length );//B_PrivateKey.txt
FS.Write( CombinData,0,CombinData.Length );
FS.Flush();
FS.Close();
string file = FileName.Text+".enc";
richbox.AppendText("\n合并结束!\n请查看合并结果文件:\n" +file + "\n三部分的长度分别为:\n" + "RsaEncryptData: " + RsaEncryptData.Length.ToString() +"\nEncryptionDate :" +EncryptionDate.Length.ToString() +"\nCombinData :" + CombinData.Length.ToString() );
int length = RsaEncryptData.Length+EncryptionDate.Length+CombinData.Length;//计算整个密文长度
richbox.AppendText("\n总的长度为: " + length.ToString());
}
private static bool state = true ;
private static RSACryptoServiceProvider icrypt ;//全局函数
private void button1_Click(object sender, System.EventArgs e)
{
if(state)
{
ShareClass.CreateXmlKey("PrivateKey.txt",icrypt.ToXmlString(true));
state = false ;
button1.Text = "产生公钥";
}
else
{
ShareClass.CreateXmlKey("PublicKey.txt",icrypt.ToXmlString(false));
state = true ;
button1.Text = "产生私钥";
button1.Enabled = false ;
}
}
private void button2_Click(object sender, System.EventArgs e)
{
icrypt = new RSACryptoServiceProvider();
button2.Enabled = false ;
}
//产生成对钥匙
private static int i = 0 ;
private void CreateXmlKeys_Click(object sender, System.EventArgs e)
{
i ++ ;
icrypt = new RSACryptoServiceProvider();
ShareClass.CreateXmlKey("PublicKey" + i.ToString()+".txt",icrypt.ToXmlString(true));
ShareClass.CreateXmlKey( "PrivateKey"+ i.ToString()+".txt",icrypt.ToXmlString(false));
MessageBox.Show("产生第" + i.ToString() + "对私钥和公钥!" );
}
//把整个加密信息分解为三部分 //分别读取到三不数组里面
private static byte [] Encrypt_One ,Encrypt_Two,Encrypt_Three ;
private void DepartBytes_Click(object sender, System.EventArgs e)
{
/* 这地方有两种数据读取方式:方式一,从文件中分离需要部分;方式二,把文件内容读取到字节数组中,然后分离数组;我们使用方式一,个人认为提供效率!*/
//打开文件,直接从文件中读取,出现错误啊
string fileName = OpenFile("请打开要解密的文件:");
//第一种读取方式:直接从文件中读取
FileStream fs = new FileStream(fileName,FileMode.Open,FileAccess.Read);
//第二种读取方式:直接读取到一个数组里面,然后对数组进行分解
// byte []fileContent = new byte[fs.Length];
// fs.Read(fileContent,0,(int)fs.Length);
richbox.AppendText("\n开始读取密文文件......");
//读取密钥密文
Encrypt_One = new byte[1152];
//方式一
fs.Read(Encrypt_One,0,1152);
richbox.AppendText("\n读取加密文件第一部分.....");
//方式二
// Buffer.BlockCopy(fileContent,0,Encrypt_One,0,1152);
//利用接收者的私钥解密
byte [] RsaDecryptionData = ShareClass.RsaDecrypt(ShareClass.OpenFile("B_PrivateKey.txt"),Encrypt_One);
richbox.AppendText("\n为分解数据解密");
//从解密出来的数组RsaDecryptionData分解出KeyIV(密钥和向量)和签名
byte [] KeyIV = new byte[16];
byte [] Signature = new byte[128];
Buffer.BlockCopy( RsaDecryptionData,0,KeyIV,0,16);
Buffer.BlockCopy( RsaDecryptionData,16,Signature,0,128 );
richbox.AppendText("\n分解出会话密钥和密钥签名");
//验证签名数据的正确与否
byte [] Key,IV;
if( ShareClass.VerifySignature( ShareClass.OpenFile( "A_PublicKey.txt" ), KeyIV, Signature ) ) //使用共钥验证签名
{//签名正确,分解密码和向量
Key = new byte[8];
IV = new byte[8];
Buffer.BlockCopy(KeyIV,0,Key,0,8);
Buffer.BlockCopy(KeyIV,8,IV,0,8);
richbox.AppendText("\n成功得到会话密钥参数:Key和IV!");
}
else
{
richbox.AppendText("\n密钥签名不正确!");
return ;
}
//读取加密的明文
// fs.Position = 0 ;
int length = (int)fs.Length-1296;// 1152-144 ; //密文的长度AllEncryptedData
Encrypt_Two = new byte[ length ];
//方式一
richbox.AppendText("\n读取密文部分......");
fs.Position = 1152 ;
fs.Read(Encrypt_Two,0,length);
//方式二
// Buffer.BlockCopy(fileContent,1152,Encrypt_Two,0,length);
//解密明文数据,还原成带时间戳的明文
byte [] DecryptionPlainText = ShareClass.DecryptData(0,Key,IV,Encrypt_Two);
richbox.AppendText( "\n使用会话密钥解密密文。" );
//MD5摘要生成
byte [] HashValue = ShareClass.HashData(0,DecryptionPlainText);//还需要和下面的摘要对比//加时间戳明文
richbox.AppendText( "\n为解密数据进行摘要。" );
//读取摘要数字
Encrypt_Three = new byte[144];
//方式一
richbox.AppendText( "\n读取摘要数字部分......" );
fs.Position = fs.Length-144 ;
fs.Read( Encrypt_Three,0,144 );
//方式二
// Buffer.BlockCopy(fileContent,fileContent.Length-144,Encrypt_Three,0,144);
//验证已经签名过的加时间戳的明文的摘要//验证摘要的签名
byte [] PlainTextHash = new byte[16];
byte [] HashSignatrue = new byte[128];
richbox.AppendText( "\n分解摘要数字部分含时间戳明文的摘要和签名" );
Buffer.BlockCopy(Encrypt_Three,0,PlainTextHash,0,16);
Buffer.BlockCopy(Encrypt_Three,16,HashSignatrue,0,128);
richbox.AppendText("开始对含时间戳明文摘要的签名进行验证......");
if( ShareClass.VerifySignature( ShareClass.OpenFile("A_PublicKey.txt"),PlainTextHash,HashSignatrue ) )//验证明文摘要
{
richbox.AppendText("\n验证加进时间戳明文的摘要的签名正确!");
//要进行摘要对比
richbox.AppendText( "\n开始比较两个含时间戳明文摘要是否相等......" );
if(ShareClass.CompareHash( HashValue,PlainTextHash )==true)
{//两散列比较相等的话//DecryptionPlainText
richbox.AppendText("\n比较两个加时间戳明文的摘要成功!");
byte [] TimeStampPart = new byte[167];
richbox.AppendText( "\n提取密文解密后的时间戳部分......" );
Buffer.BlockCopy(DecryptionPlainText,DecryptionPlainText.Length-167,TimeStampPart,0,167);
//提取与验证时间戳
richbox.AppendText( "\n提取时间戳部分摘要和签名部分......" );
byte [] HashAndTime = new byte[39];
byte [] DTSignature = new byte[128];
Buffer.BlockCopy(TimeStampPart,0,HashAndTime,0,39);
Buffer.BlockCopy(TimeStampPart,39,DTSignature,0,128);
richbox.AppendText( "\n验证时间戳签名......" );
if( ShareClass.VerifySignature( ShareClass.OpenFile("DTSPublicKey.txt"),HashAndTime,DTSignature ) )
{//验证正确
richbox.AppendText("\n验证DTS 签名成功!");
byte [] Time = new byte[23];
Buffer.BlockCopy(HashAndTime,16,Time,0,23);
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
richbox.AppendText("\nDTS 签名时间(接收文件时间):" + enc.GetString( Time,0,Time.Length ) );
//我们选择把纯明文写进文件
byte [] PurePlainText = new byte[DecryptionPlainText.Length-167];//纯明文的长度
Buffer.BlockCopy(DecryptionPlainText,0,PurePlainText,0,DecryptionPlainText.Length-167);
//判断文件的名字
string[] namePart = fileName.Split('.');
string fileRealName = namePart[0] + "." + namePart[1] ;//这样写有缺陷,还需要判断 namePart[2]是不是最后一个字符串
ShareClass.WriteFile(fileRealName,PurePlainText);
richbox.AppendText( "\n明文提取成功!\n路径为:" + fileRealName );
}
else
{
richbox.AppendText("\n验证DTS 签名失败!");
}
}
else
{
richbox.AppendText("\n比较两个加时间戳明文的摘要失败!");
}
}
fs.Close();//关闭文件读取
}
private string OpenFile(string title)
{
OpenFileDialog open = new OpenFileDialog();
open.Title = title ;//比如类似 "请打开你要产生摘要的文件:";
open.Filter = "All File (*.*)|*.*";
string FilePath = null ;
if(open.ShowDialog()==DialogResult.OK)
{
FilePath = open.FileName ;
}
return FilePath ;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -