Asp.net mvc NETMVC&;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

我想使用某种形式的“简单”加密,它相当安全,但对开发过程的影响非常小

假设我在客户机web服务情况下拥有对话的双方。我的应用程序是windows phone/win8/silverlight/desktop应用程序,服务器是ASP.Net MVC或WebAPI

在我看来,我想要一些简单的东西:-

<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);
    }