?? 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 + -