Asp.net mvc NETMVC&;WebAPI加密
我想使用某种形式的“简单”加密,它相当安全,但对开发过程的影响非常小 假设我在客户机web服务情况下拥有对话的双方。我的应用程序是windows phone/win8/silverlight/desktop应用程序,服务器是ASP.Net MVC或WebAPI 在我看来,我想要一些简单的东西:-Asp.net mvc NETMVC&;WebAPI加密,asp.net-mvc,security,asp.net-web-api,Asp.net Mvc,Security,Asp.net Web Api,我想使用某种形式的“简单”加密,它相当安全,但对开发过程的影响非常小 假设我在客户机web服务情况下拥有对话的双方。我的应用程序是windows phone/win8/silverlight/desktop应用程序,服务器是ASP.Net MVC或WebAPI 在我看来,我想要一些简单的东西:- <security encryption="off|sometype|someothertype"> <privatekey>12345MyKey54321</pr
<security encryption="off|sometype|someothertype">
<privatekey>12345MyKey54321</privatekey>
</security>
12345MyKey54321
作为客户端和服务器上的某种形式的配置参数。此外,身份验证例程将返回并存储某种形式的公钥
这样做将启用“加密模式”,并使用提供的密钥以选定的方式对任何http请求进行加密和哈希。最终的结果是,如果没有密钥和解密方法,在本地、代理或远程计算机上嗅探到的任何内容都将无法查看数据。在服务器上,在点击控制器操作之前,使用相同的密钥对数据进行解密
除了将HttpRequest/WebClient调用替换为EncryptedHttpRequest之类的调用,并在MVC/WebAPI端添加适当的钩子之外,所有其他客户端代码和控制器操作都不知道数据是加密的
我是否遗漏了一些东西,或者安装可能不是这么简单?就我所搜索的而言,没有任何东西可以提供这种程度的简单性,所以我想我的逻辑中缺少了一些漏洞?您所寻找的一切都可以通过简单地使用HTTPS来实现。只需购买一个证书(或使用自签名证书),就可以进行加密
不要重新发明轮子。我已经成功地做到了。这并不太难,而且效果很好。我使用它来激活产品的许可证。最重要的是您可以真正控制客户机和服务器—没有人可以从客户机上的代码中提取您的私钥 步骤1:创建不带参数的MVC控制器操作方法:
[HttpPost] public ActionResult Activate() { ... }
步骤2:在控制器中,只需使用HttpRequest.InputStream获取从客户端发送的字节数。
var stream=this.HttpContext.Request.InputStream
步骤3:创建要反序列化的加密流。
我在这里包括了创建加密和解密示例。sharedSecret是一个具有足够长度(512字节)的随机字节的字节[],这就是您要保护的
public CryptoStream CreateEncryptionStream(Stream writeStream)
{
TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
PasswordDeriveBytes derivedBytes = new PasswordDeriveBytes(this._sharedSecret, null);
CryptoStream cryptoStream = new CryptoStream(writeStream, cryptoProvider.CreateEncryptor(derivedBytes.GetBytes(16), derivedBytes.GetBytes(16)), CryptoStreamMode.Write);
return cryptoStream;
}
public CryptoStream CreateDecryptionStream(Stream readStream)
{
TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
PasswordDeriveBytes derivedBytes = new PasswordDeriveBytes(this._sharedSecret, null);
CryptoStream cryptoStream = new CryptoStream(readStream, cryptoProvider.CreateDecryptor(derivedBytes.GetBytes(16), derivedBytes.GetBytes(16)), CryptoStreamMode.Read);
return cryptoStream;
}
第4步:使用加密流和另一个流读取器进行解密。
我使用XmlReader,以便所有现有的序列化代码都可以以明文(在服务器上读/写磁盘或数据库时)或加密(在传输时)的方式工作
步骤5:在控制器中制定安全响应。
这与步骤1-4相反,用于加密响应对象。然后,您只需将加密响应写入内存流,并将其作为文件结果返回。下面,我展示了如何为我的许可响应对象执行此操作
var responseBytes = GetLicenseResponseBytes(licenseResponse);
return File(responseBytes, "application/octet-stream");
private byte[] GetLicenseResponseBytes(LicenseResponse licenseResponse)
{
if (licenseResponse != null)
{
using (MemoryStream memoryStream = new MemoryStream())
{
this._licenseResponseSerializer.Write(memoryStream, licenseResponse);
return memoryStream.ToArray();
}
}
return null;
}
步骤6:实施客户请求响应。
您可以使用HttpWebRequest或WebClient类来制定请求。下面是我使用的代码中的几个示例
byte[] postBytes = GetLicenseRequestBytes(licenseRequest);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(licenseServerUrl);
request.Method = "POST";
request.ContentType = "application/octet-stream";
request.Proxy = WebRequest.DefaultWebProxy;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(postBytes, 0, postBytes.Length);
}
return request;
private LicenseResponse ProcessHttpResponse(HttpWebResponse response)
{
if ((response.StatusCode == HttpStatusCode.OK) && response.ContentType.Contains("application/octet-stream"))
{
var stream = response.GetResponseStream();
if (stream != null)
{
var licenseResponse = this._licenseResponseSerializer.Read(stream);
return licenseResponse;
}
}
return new LicenseResponse(LicensingResult.Error);
}
总结和提示
- 使用客户端和服务器上的请求/响应中的流来传输二进制八位字节流数据
- 在序列化/反序列化数据时,请将CryptoStream与加密算法(考虑使用最强大的加密可能性)和良好的私钥一起使用以加密数据
- 确保检查所有传入到客户端和服务器的数据的大小和格式(避免缓冲区溢出并尽早抛出异常)
- 如果可能的话,使用模糊处理来保护您客户机上的私钥(看看深海模糊器)
问题是中间人攻击是多么容易使用像Fiddler这样的工具。伟大的解决方案!但Aliostad的答案更实际、更直截了当:)非常适合嵌入式linux机器使用此实现与数据库通信。使用Fiddler可以轻松解密HTTPS通信。
byte[] postBytes = GetLicenseRequestBytes(licenseRequest);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(licenseServerUrl);
request.Method = "POST";
request.ContentType = "application/octet-stream";
request.Proxy = WebRequest.DefaultWebProxy;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(postBytes, 0, postBytes.Length);
}
return request;
private LicenseResponse ProcessHttpResponse(HttpWebResponse response)
{
if ((response.StatusCode == HttpStatusCode.OK) && response.ContentType.Contains("application/octet-stream"))
{
var stream = response.GetResponseStream();
if (stream != null)
{
var licenseResponse = this._licenseResponseSerializer.Read(stream);
return licenseResponse;
}
}
return new LicenseResponse(LicensingResult.Error);
}