大家要有兴趣,可以一起来讨论一下 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 hwnanghb@21cn.com
/// </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);
}
}
}
}