He hecho esto con éxito. No es demasiado difícil y funciona bien. Lo uso para activar una licencia para un producto. Lo más importante es que realmente controle el cliente y el servidor; nadie puede extraer su clave privada de su código en el cliente.
Paso 1: Crear un método de acción del controlador MVC que no tiene argumentos:
[HttpPost] public ActionResult Activate() { ... }
Paso 2: En el controlador sólo tiene que utilizar el HttpRequest.InputStream a ponerme en contacto con los bytes enviados desde el cliente .
var stream = this.HttpContext.Request.InputStream;
Paso 3: Cree un CryptoStream para deserializar.
He incluido la creación de ejemplos de cifrado y descifrado aquí. SharedSecret es un byte [] de longitud suficiente (512 bytes) de bytes aleatorios. ¡Esto es lo que protege!
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;
}
Paso 4: Utilice su CryptoStream otro lector corriente para descifrar.
Utilizo un XmlReader para que todo mi código de serialización existente pueda funcionar en claro (al leer/escribir en el disco o base de datos en el servidor) o encriptado (cuando se transmite).
using (var reader = XmlReader.Create(decryptionStream, settings)) { ... }
Paso 5: formular una respuesta segura en su controlador.
Esto está haciendo lo contrario de los pasos 1-4 para encriptar su objeto de respuesta. Luego, simplemente escribe tu respuesta encriptada a una secuencia de memoria y la devuelve como un resultado de archivo. A continuación, he mostrado cómo hago esto para mi objeto de respuesta de licencia.
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;
}
Paso 6: Poner en práctica su respuesta la petición del cliente.
Puede utilizar las clases HttpWebRequest o WebClient para formular la solicitud. Aquí hay un par de ejemplos del código que uso.
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);
}
Resumen y Consejos
- Utilice las corrientes en la solicitud/respuesta en el cliente y el servidor se comuniquen los datos octava-binarios
- Uso CryptoStream junto con un algoritmo de cifrado (consideran usando la posibilidad de encriptación más fuerte) y una buena clave privada para encriptar datos cuando los serializa/deserializa.
- Asegúrese de verificar el tamaño y formato a todos los datos entrantes con el cliente y el servidor (evitar desbordamientos de búfer y lanzar excepciones temprana)
- proteger su clave privada en el cliente utilizando la ofuscación, si es posible (echar un vistazo a la obfustactor de alta mar)
Reinventando SSL/TLS ?? – Aliostad
El problema es qué fácil es que los ataques de hombre en el medio usen herramientas como Fiddler. – DannyT