C#应用程序应该向php网站发送一些数据,但应遵守auth策略 [英] C# app should send some data to php website but should respect auth policies

查看:190
本文介绍了C#应用程序应该向php网站发送一些数据,但应遵守auth策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个情况,我的C#应用​​程序需要与我的Php网站沟通(是的,我有两个来源,我可以编辑没有任何问题)。



我必须从C#应用程序发送一些数据到PHP网站来更新数据库中的一些数据。



最大的问题是,我应该发送数据的这个网页使用身份验证机制进行保护



我在编辑此机制时没有任何问题,但是我需要一种安全的发送方式最终)用户名/密码和所需的数据。什么是安全的方式来做到这一点?我不认为发送用户名和密码是纯文本是个好主意,所以我正在寻找建议。

解决方案

SSL +请求中的用户名(可选;但如果您最终有多个客户端需要区分,则可能需要)+使用与该用户名相对应的密码来标识请求,并且两端都已知。



请注意,签名并不意味着通过网络发送密码。这意味着散列一部分或完整的请求,然后将该值包含在明文请求中。收件人(PHP)会做同样的事情,然后比较哈希。签名确保只有知道密码的客户端可以发出请求;无效请求应该被拒绝。



使用SSL证书加密(如果您在php端使用),只能从好奇的眼睛隐藏数据。签名是验证客户端。



使anon php处理程序(在您的验证规则中出现异常),这应该可以工作。






编辑:示例



我们假设您希望您的C#应用​​将以下数据传递给您的PHP应用程序:

 < data> hello< / data> 

让我们说,你决定这个客户端被用户名uid 和密码pwd



签名数据涉及散列哈希意味着加密它,使得它不可能被解密(很好,我简化了;查找它)。有几种散列算法,您将不得不为C#和PHP找到一个库。最流行的(我猜)是sha1和md5。我甚至不知道核心的区别,我也不在乎。我所知道的是,不同的值被翻译到相当独特的哈希值。例如 - 尽管在主题之外,通常在数据库中存储密码的哈希值,并比较哈希值,而不是在用户验证期间比较明文密码。



在.NET中,您可以通过方法 System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile 来sha1 / md5哈希字符串值。我非常了解PHP,但我相信你会发现一个完全一样的库。



所以,给出上面的示例数据和上面的凭据,您可以执行以下操作:



1 - 查找用户名的位置(因此,您知道谁发送请求;再次,如果您预期有多个客户端;否则,在你的情况下,你可以跳过这个)。例如:

 < data username =uid> hello< / data> 

而不是这样,你可以做各种各样的事情:定义你自己的格式(xml,json,delimited,二进制),或者如果数据很短,并且您使用HTTP GET,则对其进行编码,并将数据和用户名作为两个不同的查询对,或者将其作为参数引用。



2 - 以上数据仍然是明文。现在签约这可以通过多种方式完成,但我会简单的:将明文密码添加到此数据中(无论双方知道该位置,都无关紧要);例如

 < data username =uid> hello< / data> pwd 

注意,我甚至不在乎我只是打破了xml格式。您可以将其作为属性/元素放置在任何地方。这仍然是明文。



3 - 哈希吧。再次,使用哪个哈希算法并不重要,只要双方都知道。对于这个例子,我将使用许多在线哈希生成器之一:
http://www.joeswebtools.com/security/sha1-hash-generator/



当我粘贴完整的文本(包括密码)从#2在那个网站上,我会得到这个(继续你也尝试):

  3311d4ed24ce60f7bf9cf261e3203616b239d944 $ b因此,给定完全相同的文本输入(区分大小写,编码敏感)散列会始终产生完全相同的结果。 SHA1 / MD5是固定长度算法(36和40个字符,我相信我很懒,现在要验证)。



4 - 现在,添加这个散列对#1的原始请求数据的价值(任何地点,只要双方都知道);例如:

 < data username =uid> hello< / data> 3311d4ed24ce60f7bf9cf261e3203616b239d944 

  username =uidsignature =3311d4ed24ce60f7bf9cf261e3203616b239d944> hello< / data> 

重要的是,PHP需要知道在哪里找到哈希值,以及如何解析它。



5 - 将#4中的文本从C#发送到PHP。到目前为止,我们所做的只是签署确定发件人是你认为的。它不加密:有方法来拦截此请求并读取它(但是,没有人可以解密密码)。如果你还想加密它,你可以自己去做(你关心某人是否可以阅读这个?)。有许多方法来加密数据,但是在PHP端使用SSL证书(然后通过HTTPS发送请求)可能是您最简单,最便宜,最不容易出错/冒险的方法,而且 - 我敢说 - 最好。如果您选择不加密,C#将数据发送到上述#4中。



6 - PHP收到数据。如果你使用SSL,我很确定你不需要做任何事情来解密它(由PHP为你完成) - 所以在这两种情况下,你的PHP脚本都会以明文形式收到数据。

 < data username =uidsignature =3311d4ed24ce60f7bf9cf261e3203616b239d944> hello< / data> 

7 - PHP了解此格式。如果由于任何原因解析此请求失败,请忽略该请求。我说这个假设运行在两端的代码没有与创建请求和读取相关的错误。



8 - PHP从请求数据中删除签名(同时保持在内存中),从而导致:

 < data username =uid> hello< / data> 

9 - PHP从请求(uid)中读取用户名。然后查找与之相关联的密码(pwd)。然后它执行与C#客户端在步骤#2和#3中完成的完全相同的事情,产生以下内容:

  3311d4ed24ce60f7bf9cf261e3203616b239d944 

10 - 签名表格#9的GOT与请求中提供的签名相同(从#8) - 区分大小写!如果不是,有人试图假装他们是uid客户端。



11 - 现在PHP确定客户端是其友好的C#应用​​程序(让我们称之为信任),它可以处理请求。






可能有更优雅的方式,可能更简单。另外,在第二步我告诉你添加密码,你可以添加密码的HASH(假设你的PHP甚至没有明文密码,但是它具有相同的HASH)。



不,这种方法不能伪造。我不可能 - 不知道密码 - 向您发送一些恶意形成的请求,假装是您的C#客户端。但是,重播可能。重播意味着:拦截请求,读取它,并重新发送它。这主要是为了窃取信息而没有两方知道。有一些方法可以防止重播,但是它不在范围之内,而你们没有为军队做任何事情,对吗?



现在,我想要一个A所有这些信息和我的时间:)


I have a situation where my C# Application need to communicate with my Php website (yes I have sources for both of them and I can edit without any problem).

I have to send some data from my C# app to PHP website to update some data in the database.

The biggest problem, is that this webpage where I should send data is protected with an authentication mechanism.

I don't have any problem in editing this mechanism, however I need a secure way to send (eventually) username/password and the data required. What's a secure way to do this? I don't think sending username and password as plain text is a good idea, so I was looking for suggestion.

解决方案

SSL + username in request (optional; but if you will eventually have multiple clients that you have to differentiate, it's probably necessary) + SIGN the request with the password that corresponds to that username and is known on both ends.

Note that "signing" does not mean sending the password over the network. It means hashing a part or the complete request, then including that value in clear-text request. The recipient (PHP) would then do the same, then compare hashes. Signing ensures that only the client that knows the password can make the request; invalid requests should be rejected.

Encrypting with SSL certificate (if you have it on php side) helps only to hide the data from curious eyes. Signing is what verifies the client.

Make an anon php handler (make an exception in your auth rules), and this should work.


EDIT: EXAMPLE

Let's say that you want your C# app to pass the following data to your PHP app:

<data>hello</data>

Let's say that you decided for this client to be recognized by username "uid" and password "pwd".

Signing data relates to hashing it. Hashing means encrypting it in such a way that it cannot possibly be decrypted (well, kind of; I simplified that; look it up). There are several hashing algorithms, and you'll have to find a library to do it, for both C# and PHP. The most popular (I guess) are "sha1" and "md5". I don't even know the core difference, neither do I care. All I know is that different values get to be "translated" to fairly unique hash values. For example - although, off-topic, it's common to store hash values of passwords in the database, and compare hashes, rather then be comparing clear-text password, during user validation.

In .NET, you can sha1/md5 hash string values by method System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile. I know very little about PHP, but I'm sure you'll find a library that does exactly the same.

So, given the above example data, and above credentials, you could do the following:

1 - Find the place for the username (so, that you know who's sending the request; again, if you anticipate having multiple clients; otherwise, in your case, you can skip this). For example:

<data username="uid">hello</data>

Instead of this, you can do various things: define your own format (xml, json, delimited, binary), or if the data is short and you're using HTTP GET, then encode it and have data and username be two different query pairs, or HTTP-POST them as post arguments.

2 - The above data is still clear-text. Now, signing. This can be done in multiple ways, but I'll make it simple: add the clear-text password to this data (doesn't matter where, as long that location is known to both parties); e.g.

<data username="uid">hello</data>pwd

Notice how I don't even care that I just broke the xml-format. You could have placed it as an attribute/element - anywhere. That's still clear-text.

3 - Hash it. Again, it doesn't matter which hash algorithm you use, as long it's known to both parties. For this example, I'll use one of many online hash generators that are out there: http://www.joeswebtools.com/security/sha1-hash-generator/

When I paste the complete text (including the password) from #2 over on that site, I'll get this (go ahead and you also try):

3311d4ed24ce60f7bf9cf261e3203616b239d944

So, given the exact same text input (case sensitive, encoding sensitive) hashing will always produce the exact same result. SHA1/MD5 are fixed-length algorithms (36 and 40 chars, I believe; I'm lazy to verify that right now).

4 - Now, add this hashed value to the original request data from #1 (any spot, as long as it's known to both parties); for example:

<data username="uid">hello</data>3311d4ed24ce60f7bf9cf261e3203616b239d944

or

<data username="uid" signature="3311d4ed24ce60f7bf9cf261e3203616b239d944">hello</data>

The important thing is that PHP needs to know where to find the hash value and how to parse it out.

5 - Send the text from #4 from C# to PHP. What we did so far was only signing to be certain that the sender is who you think it is. It is not encrypting: there are ways to intercept this request and read it (however, nobody can decipher the password). It is up to you if you also want to encrypt it (do you care if somebody can read this?). There are bunch of ways to encrypt data as well, but using SSL certificate on PHP side (and then sending the request over HTTPS) is probably your simplest, cheapest, the least error-prone/risky method, and - I dare say - the best. If you choose not to encrypt, C# sends the data as it is in #4 above.

6 - PHP receives the data. If you used SSL, I'm pretty sure you won't have to do anything to decrypt it (it will be done by PHP for you) - so, in either case, your PHP script will receive the data in clear-text.

<data username="uid" signature="3311d4ed24ce60f7bf9cf261e3203616b239d944">hello</data>

7 - PHP knows about this format. If parsing this request fails for any reason, ignore the request. I said this assuming that the code running on both ends has no bugs related to creating the request and reading it.

8 - PHP removes the the signature from the request data (while keeping it in memory), resulting in this:

<data username="uid">hello</data>

9 - PHP reads the username from the request ("uid"). It then looks up the password associated with it ("pwd"). It then does the exact same things that the C# client did in steps #2 and #3, producing the following for itself:

3311d4ed24ce60f7bf9cf261e3203616b239d944

10 - The signature form #9 has GOT TO be the same as the signature provided in the request (from #8) - case-sensitive! If it's not, somebody is trying to pretend they are the uid client.

11 - Now that PHP is certain that the client is its friendly C# app (let's call this "the trust"), it can process the request.


There may be more elegant ways, possibly simpler. Also, where in step #2 I told you add the password, you could instead add the HASH of the password (assuming your PHP doesn't even have the clear-text password, but it has that same HASH instead).

No, this method cannot be faked. It is impossible for me to - without knowing the password - to send you some maliciously-formed request pretending to be your C# client. However, replaying IS possible. Replaying means: intercepting the request, reading it, and resending it as it. This is mostly done to steal information without neither of the 2 parties knowing. There are ways to prevent replaying also, but it's out of scope, and you're not doing anything for the military, are you?

Now, I want an A for all this info and my time :)

这篇关于C#应用程序应该向php网站发送一些数据,但应遵守auth策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆