大家要有興趣,可以一起來討論一下 webservice數據交互安全問題,以下的這個代碼,可以用于dotnet環境下的任何托管方式的應用程序,在實際應用中有兩個實例。其中,有一個掛在internet上的,url:http://www.tttsss.com/webservice/thrdataservice.asmx , 有興趣的可以看看其中的soap信息。當然,要看里面的加密解密過程,就沒辦法了!否則,我呀太沒面子了,是吧!
前兩年寫的東西,現在整理一下發出來!以前公司需要做webservice,并且對webservice的soapheader進行加密,所以就寫了這么個東東!使用這個類,需要密鑰管理!為了保證數據的安全性往往要對數據進行加密,但是加密的缺點之一,就是影響程序的運行效率,所以,當時我的思路是只對用戶的登錄信息(用戶名,密碼)進行加密!數據用明文傳輸,用戶信息驗證沒有通過的情況下, 不進行數據傳輸。
實際在網絡通訊中,使用密鑰匙的方式并非無懈可擊,如果黑客可以捕捉到用密鑰加密的,用戶驗證信息,然后,做個模擬請求,向提供webservice的服務器發請求,還是可以獲得請求數據!所以,我又使用了ip或者域名綁定的方式!畢竟,webservice不是直接對最終用戶提供的!所以,加上以上這些手段后,就算有不良企圖者想通過非法方式獲得webservice提供的服務,就再費點勁吧!
還有一點安全建議,就是定期的更換密鑰,在這個例子中,我用的是對稱加密,加密方和解密方的密鑰一致!定期的更換密鑰可以讓安全性提高一大截!
大家要有更好的方法,或者建議,可以留言討論一下!共同提高!
代碼如下:
using system;
using system.security.cryptography ;
using system.text;
using system.io;
namespace sedo
{
/// <summary>
/// sedo 的摘要說明。
/// sedo 實現的是用一個封裝了4種對稱加密方法(des,rc2,rijndael,tripledes)的組件
///
/// 注意事項:
/// 1:tripledes和rijndael加密/解密對象使用16或者24位byte的key
/// 2:rijndael只能使用16位的初始化向量iv
/// 3:des和rc2均使用8位byte的key和iv
/// 4:對需要加密/解密的數據流采用何種方法進行編碼/解碼,由調用組件的用戶自己決定
/// 5:密鑰和初始化向量iv由使用者自己定義
/// 程序員: 王海波 2003-05-19 [email protected]
/// </summary>
//定義加密類型的枚舉
public enum encryptionalgorithm {des = 1, rc2, rijndael, tripledes};
//定義加密類
internal class encrypttransformer
{
private encryptionalgorithm algorithmid;
private byte[] initvec;
private byte[] enckey;
internal encrypttransformer(encryptionalgorithm algid)
{
//save the algorithm being used.
algorithmid = algid;
}
internal icryptotransform getcryptoserviceprovider(byte[] byteskey)
{
//當數據密鑰key或者初始化向量iv為空的時候,將使用加密對象自動產生的密鑰key或者初始化向量iv
switch (algorithmid)
{
case encryptionalgorithm.des:
{
des des = new descryptoserviceprovider();
des.mode = ciphermode.cbc;
// see if a key was provided
if (null == byteskey)
{
enckey = des.key;
}
else
{
des.key = byteskey;
enckey = des.key;
}
// see if the client provided an initialization vector
if (null == initvec)
{ // have the algorithm create one
initvec = des.iv;
}
else
{ //no, give it to the algorithm
des.iv = initvec;
}
return des.createencryptor();
}
case encryptionalgorithm.tripledes:
{
tripledes des3 = new tripledescryptoserviceprovider();
des3.mode = ciphermode.cbc;
// see if a key was provided
if (null == byteskey)
{
enckey = des3.key;
}
else
{
des3.key = byteskey;
enckey = des3.key;
}
// see if the client provided an iv
if (null == initvec)
{ //yes, have the alg create one
initvec = des3.iv;
}
else
{ //no, give it to the alg.
des3.iv = initvec;
}
return des3.createencryptor();
}
case encryptionalgorithm.rc2:
{
rc2 rc2 = new rc2cryptoserviceprovider();
rc2.mode = ciphermode.cbc;
// test to see if a key was provided
if (null == byteskey)
{
enckey = rc2.key;
}
else
{
rc2.key = byteskey;
enckey = rc2.key;
}
// see if the client provided an iv
if (null == initvec)
{ //yes, have the alg create one
initvec = rc2.iv;
}
else
{ //no, give it to the alg.
rc2.iv = initvec;
}
return rc2.createencryptor();
}
case encryptionalgorithm.rijndael:
{
rijndael rijndael = new rijndaelmanaged();
rijndael.mode = ciphermode.cbc;
// test to see if a key was provided
if(null == byteskey)
{
enckey = rijndael.key;
}
else
{
rijndael.key = byteskey;
enckey = rijndael.key;
}
// see if the client provided an iv
if(null == initvec)
{ //yes, have the alg create one
initvec = rijndael.iv;
}
else
{ //no, give it to the alg.
rijndael.iv = initvec;
}
return rijndael.createencryptor();
}
default:
{
throw new cryptographicexception("algorithm id '" +
algorithmid +
"' not supported.");
}
}
}
//加密的偏移向量
internal byte[] iv
{
get{return initvec;}
set{initvec = value;}
}
//加密的密鑰
internal byte[] key
{
get{return enckey;}
set{enckey = value;}
}
}
//定義解密類
internal class decrypttransformer
{
private encryptionalgorithm algorithmid;
private byte[] initvec;
private byte[] enckey;
internal decrypttransformer(encryptionalgorithm decryptid)
{
algorithmid = decryptid;
}
//加密的偏移向量
internal byte[] iv
{
get{return initvec;}
set{initvec = value;}
}
//加密的密鑰
internal byte[] key
{
get{return enckey;}
set{enckey = value;}
}
internal icryptotransform getcryptoserviceprovider(byte[] byteskey)
{
//當數據密鑰key或者初始化向量iv為空的時候,將使用加密對象自動產生的密鑰key或者初始化向量iv
switch (algorithmid)
{
case encryptionalgorithm.des:
{
des des = new descryptoserviceprovider();
des.mode = ciphermode.cbc;
des.key = byteskey;
des.iv = initvec;
return des.createdecryptor();
}
case encryptionalgorithm.tripledes:
{
tripledes des3 = new tripledescryptoserviceprovider();
des3.mode = ciphermode.cbc;
return des3.createdecryptor(byteskey, initvec);
}
case encryptionalgorithm.rc2:
{
rc2 rc2 = new rc2cryptoserviceprovider();
rc2.mode = ciphermode.cbc;
return rc2.createdecryptor(byteskey, initvec);
}
case encryptionalgorithm.rijndael:
{
rijndael rijndael = new rijndaelmanaged();
rijndael.mode = ciphermode.cbc;
return rijndael.createdecryptor(byteskey, initvec);
}
default:
{
throw new cryptographicexception("algorithm id '" +
algorithmid +
"' not supported.");
}
}
} //end getcryptoserviceprovider
}
//定義加密者類
public class encryptor
{
private encrypttransformer transformer;
private byte[] initvec;
private byte[] enckey;
public encryptor(encryptionalgorithm algid)
{
transformer = new encrypttransformer(algid);
}
public byte[] encrypt(byte[] bytesdata, byte[] byteskey,byte[] bytesiv)
{
//設置流對象用來保存加密數據字節流.
memorystream memstreamencrypteddata = new memorystream();
transformer.iv=bytesiv;
transformer.key=byteskey;
icryptotransform transform = transformer.getcryptoserviceprovider(byteskey);
cryptostream encstream = new cryptostream(memstreamencrypteddata,transform,cryptostreammode.write);
try
{
//將加密數據寫進流對象
encstream.write(bytesdata, 0, bytesdata.length);
}
catch(exception ex)
{
throw new exception("在數據加密的時候出現錯誤!錯誤提示: /n" + ex.message);
}
//設置加密的key和初始向量iv屬性
enckey = transformer.key;
initvec = transformer.iv;
encstream.flushfinalblock();
encstream.close();
//send the data back.
return memstreamencrypteddata.toarray();
}
public byte[] iv
{
get{return initvec;}
set{initvec = value;}
}
public byte[] key
{
get{return enckey;}
set{enckey = value;}
}
}
//定義解密者類
public class decryptor
{
private decrypttransformer transformer;
private byte[] initvec;
private byte[] enckey;
public decryptor(encryptionalgorithm algid)
{
transformer = new decrypttransformer(algid);
}
public byte[] decrypt(byte[] bytesdata, byte[] byteskey,byte[] bytesiv)
{
//設置流對象用來保存解密數據字節流.
memorystream memstreamdecrypteddata = new memorystream();
//pass in the initialization vector.
transformer.iv = bytesiv;
transformer.key = byteskey;
icryptotransform transform = transformer.getcryptoserviceprovider(byteskey);
cryptostream decstream = new cryptostream(memstreamdecrypteddata,transform, cryptostreammode.write);
try
{
decstream.write(bytesdata, 0, bytesdata.length);
}
catch(exception ex)
{
throw new exception("在數據解密的時候出現錯誤!錯誤提示: /n" + ex.message);
}
decstream.flushfinalblock();
decstream.close();
// 返回解密數據.
return memstreamdecrypteddata.toarray();
}
public byte[] iv
{
get{return initvec;}
set{initvec = value;}
}
public byte[] key
{
get{return enckey;}
set{enckey = value;}
}
}
//類描述:文件加密/解密類
public class securityfile
{
private decrypttransformer dec_transformer; //解密轉換器
private encrypttransformer enc_transformer; //加密轉換器
private byte[] initvec;
private byte[] enckey;
public securityfile(encryptionalgorithm algid)
{
dec_transformer = new decrypttransformer(algid);
enc_transformer = new encrypttransformer(algid);
}
//加密的偏移向量
internal byte[] iv
{
get{return initvec;}
set{initvec = value;}
}
//加密的密鑰
internal byte[] key
{
get{return enckey;}
set{enckey = value;}
}
//功能描述:加密文件
public void encryptfile(string infilename, string outfilename, byte[] byteskey, byte[] bytesiv)
{
try
{
filestream fin = new filestream(infilename, filemode.open, fileaccess.read);
filestream fout = new filestream(outfilename, filemode.openorcreate, fileaccess.write);
fout.setlength(0);
//create variables to help with read and write.
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.
enc_transformer.iv=bytesiv;
enc_transformer.key=byteskey;
icryptotransform transform = enc_transformer.getcryptoserviceprovider(byteskey);
cryptostream encstream = new cryptostream(fout, transform, 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(exception ex)
{
throw new exception("在文件加密的時候出現錯誤!錯誤提示: /n" + ex.message);
}
}
//功能描述:解密文件
public void decryptfile(string infilename, string outfilename, byte[] byteskey, byte[] bytesiv)
{
try
{
filestream fin = new filestream(infilename, filemode.open, fileaccess.read);
filestream fout = new filestream(outfilename, filemode.openorcreate, fileaccess.write);
fout.setlength(0);
//create variables to help with read and write.
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.
dec_transformer.iv=bytesiv;
dec_transformer.key=byteskey;
icryptotransform transform = dec_transformer.getcryptoserviceprovider(byteskey);
cryptostream encstream = new cryptostream(fout, transform, 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(exception ex)
{
throw new exception("在文件加密的時候出現錯誤!錯誤提示: /n" + ex.message);
}
}
}
}