我想利用某种形式的“简单”加密,这种加密在一定程度上是安全的,但是对开发过程的影响却很小。假设我在客户端 Web服务情况下拥有对话的双方。我的应用程序是Windows Phone / win8 / silverlight /桌面应用程序,服务器是ASP.Net MVC或WebAPI。在我看来,我想要简单的东西:<security encryption="off|sometype|someothertype"> <privatekey>12345MyKey54321</privatekey></security>作为客户端和服务器上的某种形式的配置参数。此外,身份验证例程将返回并存储某种形式的公钥。这样做将启用“加密模式”,并导致使用提供的密钥以选择的方式对任何http请求进行加密和哈希处理。如果没有密钥和解密方法,最终结果是在本地,代理或远程计算机上嗅探到的任何内容将无法查看数据。在服务器上,在执行控制器操作之前,使用相同的密钥解密数据。除了换出HttpRequest / WebClient调用诸如EncryptedHttpRequest之类的东西并在MVC / WebAPI方面添加适当的钩子之外,所有其他客户端代码和控制器操作都不知道数据已加密。我是否缺少某些东西,或者设置可能不是那么简单?就我所搜索的而言,没有什么可以提供这种简单性,因此我认为我的逻辑缺少一些明显的缺陷? (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 我已经成功地做到了。它不太困难并且运行良好。我用它来激活产品的许可证。最重要的是,您可以真正控制客户端和服务器-没有人可以从客户端上的代码中提取私钥。步骤1:创建不带参数的MVC控制器操作方法:[HttpPost] public ActionResult Activate() { ... }步骤2:在控制器中,只需使用HttpRequest.InputStream即可获取从客户端发送的字节。var stream = this.HttpContext.Request.InputStream;步骤3:创建要反序列化的CryptoStream。我在此处包括创建加密和解密示例。 sharedSecret是一个足够长(512个字节)随机字节的byte []-这是您要保护的!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:使用您的CryptoStream另一个流读取器进行解密。我使用XmlReader,以便所有现有的序列化代码都可以以明文形式(在服务器上对磁盘或数据库进行读/写时)或加密(在传输时)进行工作。using (var reader = XmlReader.Create(decryptionStream, settings)) { ... }步骤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与加密算法(考虑使用最强的加密方式)和良好的私钥一起使用来加密数据。确保检查大小,并格式化所有传入到客户端和服务器的数据(避免缓冲区溢出并尽早抛出异常)如果可能的话,使用混淆来保护客户端的私钥(请查看DeepSea的混淆器) (adsbygoogle = window.adsbygoogle || []).push({});
08-28 22:55