📄 shareclass.cs
字号:
using System;
using System.IO ;
using System.Data ;
using System.Windows.Forms;
using System.Security.Cryptography;
namespace Encryption_Demo
{
/// <summary>
/// 目的在工程中直接引用
/// </summary>
public class ShareClass
{
public ShareClass()
{
}
//选择HASH方式
private static string [] hashs = new string[5]{"MD5","SHA256","SHA384","SHA512","SHA1"};
//散列文件函数,得到文件摘要
public static byte [] HashFile(int choice,string filepath )//返回散列后的结果
{
FileStream fs = new FileStream(filepath ,FileMode.Open,FileAccess.Read );
HashAlgorithm shas = HashAlgorithm.Create( hashs [choice]);
byte [] TheHashResult = shas.ComputeHash( fs );
fs.Close();
shas.Clear();
return TheHashResult ;//Convert.ToBase64String( TheHashResult ,0 ,TheHashResult.Length );
}
//散列数据啦
public static byte[] HashData(int choice,byte []hashdata)
{
HashAlgorithm shas = HashAlgorithm.Create( hashs [choice]);
byte [] hashed = shas.ComputeHash(hashdata,0,hashdata.Length);
return hashed ;
}
//比较两个散列是否相等
public static bool CompareHash( byte[]hashA,byte[]hashB )
{
if(hashA.Length != hashB.Length )
throw new ArgumentException(" The Hashes must be same length ! ");
bool match = true ;
for( int i=0;i<hashA.Length;i++ )
{
if( hashA[i] != hashB[i])
match = false ;
}
return match;
}
//得到收到文件的时间,转化为数组形式
public static byte [] GetTimeNow()
{
//这样转化成的格式为:2004-11-09 13:04:28-108 23个字节
DateTime now = DateTime.Now;
System.Text.UTF8Encoding utf = new System.Text.UTF8Encoding();
string month = null ;
if(now.Month<10)
month = "0"+now.Month.ToString();
else
month = now.Month.ToString();
string day = null;
if(now.Day<10)
day = "0" + now.Day.ToString();
else
day = now.Day.ToString();
string millisecond = null;
if(now.Millisecond<10)
millisecond = "00"+now.Millisecond.ToString();
if(now.Millisecond>=10&&now.Millisecond<=99)
millisecond = "0" + now.Millisecond.ToString();
if(now.Millisecond>=100)
millisecond = now.Millisecond.ToString();
string FullFormatTime = now.Year.ToString() + "-" + month + "-" + day + " " + now.ToLongTimeString() + "-" + millisecond ;//比如:2004-11-09 13:04:28-108
return utf.GetBytes( FullFormatTime );//now.ToString() + "-"+now.Millisecond);//now.Millisecond 表示当前日期的毫秒部分
}
/// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//对称加密与解密函数
private static SymmetricAlgorithm crypt; //全局必须是静态
private static string [] sma = new string[4]{"DES","TripleDES","RC2","Rijndael"};
//随机产生对称加密的钥匙KEY和向量IV
public static byte [] RandomKey(int choice)
{
SymmetricAlgorithm crypt = SymmetricAlgorithm.Create(sma[choice]);
crypt.GenerateKey();
return crypt.Key ;
}
public static byte [] RandomIV(int choice)
{
SymmetricAlgorithm crypt = SymmetricAlgorithm.Create(sma[choice]);
crypt.GenerateIV();
return crypt.IV ;
}
//对称加密数据函数
public static byte [] EncryptData( int choice,byte[]Key,byte[]IV,byte[]toEncryptData )
{
try
{
SymmetricAlgorithm crypt = SymmetricAlgorithm.Create(sma[choice]);
ICryptoTransform transform = crypt.CreateEncryptor( Key,IV);
//Encrypt the data.
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms ,transform, CryptoStreamMode.Write);
//Convert the data to a byte array.
//Write all data to the crypto stream and flush it.
cs.Write(toEncryptData, 0, toEncryptData.Length);
cs.FlushFinalBlock();
//Get encrypted array of bytes.
return ms.ToArray();
}
catch
{
throw new CryptographicException("加密出现失误,请重新检查输入!");
}
}
//解密数据,根据思路,此时byte[]Key,byte[]IV这些参数不再是随机的数据而是固定的数据啦。
public static byte[] DecryptData( int choice ,byte[]Key,byte[]IV ,byte[]toDecryptedData )
{
try
{
SymmetricAlgorithm crypt = SymmetricAlgorithm.Create(sma[choice]);
ICryptoTransform transform = crypt.CreateDecryptor( Key,IV );
MemoryStream ms = new MemoryStream( );
//重写这部分
CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
//Read the data out of the crypto stream.
cs.Write( toDecryptedData , 0, toDecryptedData.Length);
cs.FlushFinalBlock();
return ms.ToArray() ;
}
catch
{
throw new CryptographicException("解密数据流时,出现错误,请检查您的输入!");
}
}
//加密与解密文件
public static void EncryptFile(int choice ,String inName, String outName ,byte[]Key,byte[]IV)
{
try
{
//Create the file streams to handle the input and output files.
FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);
FileStream fout = new FileStream(outName, FileMode.Append, FileAccess.Write);
fout.SetLength(0);
byte[] bin = new byte[100]; //This is intermediate storage for the encryption.
long rdlen = 0; //This is the total number of bytes written.
long totlen = fin.Length; //This is the total length of the input file.
int len; //This is the number of bytes to be written at a time.
crypt = SymmetricAlgorithm.Create(sma[choice]);
CryptoStream encStream = new CryptoStream(fout,crypt.CreateEncryptor(Key,IV), CryptoStreamMode.Write);
//Read from the input file, then encrypt and write to the output file.
while(rdlen < totlen)
{
len = fin.Read(bin, 0, 100);
encStream.Write(bin, 0, len);
rdlen = rdlen + len;
}
encStream.Close();
fout.Close();
fin.Close();
}
catch
{
throw new CryptographicException("加密文件流时,出现错误,请检查您的输入!");
}
}
//重写这部分,因为使用上有些问题
public static byte [] EncryptFile(int choice,string filename,byte[]Key,byte[]IV)
{
FileStream fs = new FileStream(filename,FileMode.Open,FileAccess.Read);
byte []fileContent = new byte[fs.Length];
fs.Read( fileContent ,0,(int)fs.Length); //这样限制了文件的长度啦!
fs.Close();
crypt = SymmetricAlgorithm.Create(sma[choice]);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms,crypt.CreateEncryptor(Key,IV), CryptoStreamMode.Write);
cs.Write(fileContent,0,fileContent.Length);
cs.FlushFinalBlock();
return ms.ToArray();
}
//对文件的数据进行加密
public static byte [] EncryptFile(int choice,byte[]fileContent,byte[]Key,byte[]IV)
{
crypt = SymmetricAlgorithm.Create(sma[choice]);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms,crypt.CreateEncryptor(Key,IV), CryptoStreamMode.Write);
cs.Write(fileContent,0,fileContent.Length);
cs.FlushFinalBlock();
return ms.ToArray();
}
//解密方案失误,经过修改,需要测试
public static void DecryptFile( int choice,String inName, String outName ,byte[]Key,byte[]IV)
{
try
{
FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);
FileStream fout = new FileStream(outName, FileMode.Append, FileAccess.Write);
fout.SetLength(0);
byte[] bin = new byte[100]; //This is intermediate storage for the encryption.
long rdlen = 0; //This is the total number of bytes written.
long totlen = fin.Length; //This is the total length of the input file.
int len; //This is the number of bytes to be written at a time.
crypt = SymmetricAlgorithm.Create(sma[choice]);
CryptoStream encStream = new CryptoStream(fout,crypt.CreateDecryptor(Key,IV), CryptoStreamMode.Write); //已经改动
while(rdlen < totlen)
{
len = fin.Read(bin,0,100);
encStream.Write(bin,0,len);
rdlen = rdlen + len ;
}
encStream.Close();
fout.Close();
fin.Close();
}
catch
{
throw new CryptographicException("解密文件流时,出现错误,请检查您的输入!");
}
}
//重写解密这部分
public static byte [] DecryptFile(int choice,byte[]fileContent,byte[]Key,byte[]IV)
{
crypt = SymmetricAlgorithm.Create(sma[choice]);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms,crypt.CreateDecryptor(Key,IV), CryptoStreamMode.Write);
cs.Write(fileContent,0,fileContent.Length);
cs.FlushFinalBlock();
return ms.ToArray();
}
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//签名函数
//直接签名的函数 //需要导入钥匙,当利用到钥匙容器,不再需要直接导入钥匙,需要再填写一个函数
private static RSACryptoServiceProvider icrypt ;//全局函数
//签名函数
private static byte[] Signature( byte[] data )
{
byte [] signature = icrypt.SignData(data,0,data.Length,MD5.Create() );//采用MD5格式签名
return signature;
}
//产生事例
public static void SetInstance()
{
icrypt = new RSACryptoServiceProvider();
}
//从外部导入钥匙,密和私的钥匙
public static string XmlString(bool pub)
{
// SetInstance();
return icrypt.ToXmlString( pub );
}
private static void Key_FromXmlString( string rsakey )
{
try
{
icrypt.FromXmlString( rsakey );
}
catch
{
MessageBox.Show("导入钥匙失败!");
}
}
//可以在外部直接引用这个函数
//下面为签名与验证函数
//签名函数,为数据data签名
public static byte [] Sinature(string PriKeyXmlPath,byte[] data)
{
SetInstance();
try
{
Key_FromXmlString( ReadXmlKey( PriKeyXmlPath ) ); //导入私钥
}
catch
{
MessageBox.Show("导入私钥失败,请检查原因!");
}
return icrypt.SignData(data,0,data.Length,MD5.Create());
}
//验证签名数据,公钥验证签名,signedata为已经签名的数据,tosigndata为要要验证的签名数据
public static bool VerifySignature( string PubKeyXmlPath ,byte[]signedata,byte [] tosigndata )//,string publickey ) //RSAParameters DSAKeyInfo)
{
bool VerifyResult = false;
SetInstance();
try
{
Key_FromXmlString( ReadXmlKey( PubKeyXmlPath ) ); //导入公钥
}
catch
{
MessageBox.Show("导入公钥失败,请检查原因!");
}
try
{
VerifyResult = icrypt.VerifyData( signedata,MD5.Create(), tosigndata);
}
catch //(CryptographicException e)
{
}
return VerifyResult;
}
//下面为使用公钥加密数据,私钥解密数据
//使用公钥加密数据
public static byte [] RsaEncrypt(string PubKeyXmlPath ,byte [] bytes)
{
try
{
Key_FromXmlString( ReadXmlKey( PubKeyXmlPath ) ); //导入公钥
}
catch
{
MessageBox.Show("导入公钥失败,请检查原因!");
}
MemoryStream ms=new MemoryStream();
int blockSize=0;
if(icrypt.KeySize==1024)
blockSize=16;
else
blockSize=8;
byte[]rawblock,encryblock;
for(int i=0;i<bytes.Length;i+=blockSize)
{
if((bytes.Length-i)>blockSize)
rawblock=new byte[blockSize];
else
rawblock =new byte[bytes.Length-i];
Buffer.BlockCopy(bytes,i,rawblock,0,rawblock.Length);
encryblock=icrypt.Encrypt(rawblock,false);
ms.Write(encryblock,0,encryblock.Length);
}
ms.Position=0;
byte [] encode=new byte[ms.Length];
ms.Read(encode,0,(int)ms.Length);
ms.Close();
return encode;
}
//使用私钥解密(公钥加密的数据)
public static byte [] RsaDecrypt(string PriKeyXmlPath ,byte [] bytes)
{
SetInstance();
try
{
Key_FromXmlString( ReadXmlKey( PriKeyXmlPath ) ); //导入私钥
}
catch
{
MessageBox.Show("导入私钥失败,请检查原因!");
}
MemoryStream ms=new MemoryStream();
int keySize=icrypt.KeySize/8;
byte[]rawblock,decryptblock;
for(int i=0;i<bytes.Length;i+=keySize)
{
if( ( bytes.Length-i ) > keySize )
{
rawblock=new byte[keySize];
}
else
{
rawblock =new byte[bytes.Length-i];
}
Buffer.BlockCopy(bytes,i,rawblock,0,rawblock.Length);
//问题的所在的地方,要注意查找其真实原因!!!!!!!!!!!!
decryptblock = icrypt.Decrypt( rawblock,false );
ms.Write(decryptblock,0,decryptblock.Length);
}
ms.Position=0;
byte [] decode=new byte[ms.Length];
ms.Read(decode,0,(int)ms.Length);
ms.Close();
return decode ;//icrypt.Encrypt( data,false );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//合并两个数组或者三个数组
//把第1个数组插接到第2个数组的后面。
public static byte [] CombinBytes(byte[]dataone,byte[]datatwo)
{
MemoryStream ms =new MemoryStream();
ms.Write(datatwo,0,datatwo.Length);
ms.Write(dataone,0,dataone.Length);
ms.Position = 0 ;
return ms.ToArray();
}
//写文件
public static void WriteFile( string filepath,byte[]RsaEncryptData)
{
FileStream fs = new FileStream(filepath,FileMode.Append,FileAccess.Write);
fs.Write(RsaEncryptData,0,RsaEncryptData.Length);
fs.Flush();
fs.Close();
}
private static string ReadXmlKey(string path)
{
string XmlKey;
try
{
StreamReader sr = new StreamReader(path);
XmlKey = sr.ReadToEnd();
sr.Close();
}
catch
{
XmlKey = null ;
MessageBox.Show("读取文件失败,请检查原因!");
}
return XmlKey ;
}
public static 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 ;
}
public static void CreateXmlKey(string path,string key)
{
StreamWriter sw = new StreamWriter(path);
sw.Write( key );
sw.Flush();
sw.Close();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -