webService 接口加密问题

yaochutao 2011-04-29 11:52:19
大家好!

服务器有一个webService 接口A

怎么样才能保证只有我的程序(有很多,程序是在客户那边的)才能调用 "接口A" ,其实我是担心人家恶意灌水。
请大家给个思路,谢谢。


====================================================================================
我看过其他人的做法是在每次调用的时候都会返回一串随机的几十位的验证码给接口。
我有点不明白的接口怎么知道这串验证码是合法的。
...全文
238 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
子夜__ 2011-05-03
  • 打赏
  • 举报
回复
机器人 2011-04-29
  • 打赏
  • 举报
回复
看你的问题,主要是客户端的身份验证。你说的”一串随机的几十位的验证码”是一种用户密码方式的验证。
(Token)
参考:http://www.codeproject.com/KB/cpp/SecurityTokens.aspx

另外还可以从以下几个方面处理:
1. 不公开WSDL,WSDL可以通过别的途径分发。(不知道服务的地址,别人也无法调用)
2. 身份验证,这点可以用传统的用户名密码(SoapHeader),
还可以用windows身份验证(不适合公网),还有用客户端证书验证
3. 消息本身加密,客户端和服务端对SoapMessage可以进行加密。
4. 再往下,就是通道加密,使用SSL。

ycproc 2011-04-29
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 yaochutao 的回复:]

Response.Write(x.Decrypting(de.Encrypting("ok","yyy"),"yyy")); 各个参数何解?
[/Quote]

自定义的
yaochutao 2011-04-29
  • 打赏
  • 举报
回复
Response.Write(x.Decrypting(de.Encrypting("ok","yyy"),"yyy")); 各个参数何解?
yaochutao 2011-04-29
  • 打赏
  • 举报
回复
潇洒哥,是什么原理。
[Quote=引用楼主 yaochutao 的回复:]
大家好!

服务器有一个webService 接口A

怎么样才能保证只有我的程序(有很多,程序是在客户那边的)才能调用 "接口A" ,其实我是担心人家恶意灌水。
请大家给个思路,谢谢。


====================================================================================
我看过其他人的做法是……
[/Quote]
BaoShiqiang 2011-04-29
  • 打赏
  • 举报
回复
提供一个基于.NET SymmetricAlgorithm 类的、带私钥的加密/解密算法的包装类。使用方法:



SymmCrypto de = new SymmCrypto(SymmCrypto.SymmProvEnum.DES);
Response.Write(x.Decrypting(de.Encrypting("ok","yyy"),"yyy"));
类的实现C#编码

using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;

namespace eMeng
{
/// <summary>
/// SymmCrypto 的摘要说明。
/// SymmCrypto类实现.NET框架下的加密和解密服务。
/// 原作者: Frank Fang : fangfrank@hotmail.com
/// </summary>
public class SymmCrypto
{
public enum SymmProvEnum : int
{
DES, RC2, Rijndael
}

private SymmetricAlgorithm mobjCryptoService;

/// <remarks>
/// 使用.Net SymmetricAlgorithm 类的构造器.
/// </remarks>
public SymmCrypto(SymmProvEnum NetSelected)
{
switch (NetSelected)
{
case SymmProvEnum.DES:
mobjCryptoService = new DESCryptoServiceProvider();
break;
case SymmProvEnum.RC2:
mobjCryptoService = new RC2CryptoServiceProvider();
break;
case SymmProvEnum.Rijndael:
mobjCryptoService = new RijndaelManaged();
break;
}
}

/// <remarks>
/// 使用自定义SymmetricAlgorithm类的构造器.
/// </remarks>
public SymmCrypto(SymmetricAlgorithm ServiceProvider)
{
mobjCryptoService = ServiceProvider;
}

/// <remarks>
/// Depending on the legal key size limitations of
/// a specific CryptoService provider and length of
/// the private key provided, padding the secret key
/// with space character to meet the legal size of the algorithm.
/// </remarks>
private byte[] GetLegalKey(string Key)
{
string sTemp;
if (mobjCryptoService.LegalKeySizes.Length > 0)
{
int lessSize = 0, moreSize = mobjCryptoService.LegalKeySizes[0].MinSize;
// key sizes are in bits
while (Key.Length * 8 > moreSize)
{
lessSize = moreSize;
moreSize += mobjCryptoService.LegalKeySizes[0].SkipSize;
}
sTemp = Key.PadRight(moreSize / 8, ' ');
}
else
sTemp = Key;

// convert the secret key to byte array
return ASCIIEncoding.ASCII.GetBytes(sTemp);
}

public string Encrypting(string Source, string Key)
{
byte[] bytIn = System.Text.ASCIIEncoding.ASCII.GetBytes(Source);
// create a MemoryStream so that the process can be done without I/O files
System.IO.MemoryStream ms = new System.IO.MemoryStream();

byte[] bytKey = GetLegalKey(Key);

// set the private key
mobjCryptoService.Key = bytKey;
mobjCryptoService.IV = bytKey;

// create an Encryptor from the Provider Service instance
ICryptoTransform encrypto = mobjCryptoService.CreateEncryptor();

// create Crypto Stream that transforms a stream using the encryption
CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);

// write out encrypted content into MemoryStream
cs.Write(bytIn, 0, bytIn.Length);
cs.FlushFinalBlock();

// get the output and trim the '\0' bytes
byte[] bytOut = ms.GetBuffer();
int i = 0;
for (i = 0; i < bytOut.Length; i++)
if (bytOut[i] == 0)
break;

// convert into Base64 so that the result can be used in xml
return System.Convert.ToBase64String(bytOut, 0, i);
}

public string Decrypting(string Source, string Key)
{
// convert from Base64 to binary
byte[] bytIn = System.Convert.FromBase64String(Source);
// create a MemoryStream with the input
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn, 0, bytIn.Length);

byte[] bytKey = GetLegalKey(Key);

// set the private key
mobjCryptoService.Key = bytKey;
mobjCryptoService.IV = bytKey;

// create a Decryptor from the Provider Service instance
ICryptoTransform encrypto = mobjCryptoService.CreateDecryptor();

// create Crypto Stream that transforms a stream using the decryption
CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);

// read out the result from the Crypto Stream
System.IO.StreamReader sr = new System.IO.StreamReader( cs );
return sr.ReadToEnd();
}
}
}

hwbox 2011-04-29
  • 打赏
  • 举报
回复
刚回答了个差不多的问题,复制一下:

如果你的网站为A
传来参数的为B

请问B网站用什么传参来的?
方式一、是后台用 WebClient
方式二、还是B网站有一个页面,用户浏览这个页面点击提交(或ajax提交)后提交到A网站?
此方法,的验证基本上就是js的范围了。我就不多说了。

方式一正好和我的一个应用中的情况一样我来说说吧。

方式一的互信方式很多种,最简单的双方约定对称密钥和暗语。传递的数据 s 。
首先 sa = 暗语 + s
然后 sb = 随机密钥加密(sa)
然后 sc = 随机密钥 + sb
然后 sd = 约定密钥加密(sc)
发送sd

接收方 收到 sd
sc = 约定密钥解密
得到 sc 分解为 随机密钥 + sb
sa = 随机密钥解密(sb)
sa 分解为 暗语 + s
检查 暗语
通过
入库 s

双重加密是可以有效的混淆加密结果。
缺点,攻击方可以反复发送同样的串攻击。

加强方案一,增加受信回访步骤。

A在发送前生成 一个随机 guid,放入本机 Dictionary <guid,datatime>中。
将guid和数据一同发送。
B收到后访问A上的页面Achack.ashx提交得到的guid,A检查发现后返回B true 同时删除 指定的 Guid 项。B确认后 数据 s 入库

缺点,多次确认,比较费时。

加强方案二,增加唯一标识窗标识。
A在发送时同时发送生成 一个随机 guid,和当前系统时间(两者相加确保不重)
B端库中确保用 guid + datatim + id 做主键。这样反复发送的数据就入不了库了。

缺点,受攻击时还是会进行入库操作。

加强方案三,在方案二的基础上在B端本地维持一个缓冲对象,记录一分钟内提交的所有信息。有重复提交的就忽略。
可以用SortedDictionary 加自定义比较器的方法实现 既支持 key 值直接定位,又支持按 value 中的某项排序。

  • 打赏
  • 举报
回复
简单的身份验证 高深的就不知道了

62,047

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧