// envia el mensaje (desde el servicio) internal void Envia() { buzon_billete.PonLong(0, 0); buzon_indice.PonInt(0, 0); buzon_longitud.PonInt(0, buzon_mensaje.Longitud); // Buzon secreto = seguridad.GeneraSecreto(); // Buzon.CopiaDatos(secreto, this.buzon_secreto); Buzon.CopiaDatos(Seguridad.protocolo, this.buzon_protocolo); // CifradoRSA cifrado_RSA = new CifradoRSA(); try { cifrado_RSA.IniciaPublica(seguridad.clave_publica); cifrado_RSA.CifraPublica(buzon_texto, buzon_cifrado); } finally { cifrado_RSA.Termina(); } // conexion.EnviaSocket(buzon_mensaje, buzon_mensaje.Longitud); // seguridad.ImprimeEnvia( buzon_billete, buzon_indice, buzon_longitud, "RSA ( S1 | protocolo )"); // seguridad.EstableceSecreto(secreto); }
// recibe el mensaje (en el cliente) internal void Recibe() { conexion.RecibeSocket(buzon_mensaje, 0, buzon_mensaje.Longitud); // seguridad.ImprimeRecibe( buzon_billete, buzon_indice, buzon_longitud, "RSA ( S1 | protocolo )"); // // se valida el mensaje if (buzon_billete.TomaInt(0) != 0 || buzon_indice.TomaInt(0) != 0 || buzon_longitud.TomaInt(0) != buzon_mensaje.Longitud) { throw new ErrorConexion("Violación del protocolo de seguridad."); } // CifradoRSA cifrado_RSA = new CifradoRSA(); try { cifrado_RSA.IniciaPrivada(seguridad.seguridad_servidor.clave_privada); cifrado_RSA.DescifraPrivada(buzon_cifrado, buzon_texto); } finally { cifrado_RSA.Termina(); } // if (!Buzon.DatosIguales(this.buzon_protocolo, Seguridad.protocolo)) { throw new ErrorConexion("Protocolo de seguridad inconsistente."); } // seguridad.EstableceSecreto(this.buzon_secreto); }
/// <summary> /// Calcula el código HMAC del mensaje y lo deja en el buzón indicado. /// </summary> /// <remarks> /// El buzón 'valor_HMAC' puede ser vacío; en ese caso se crea un array de bytes de longitud /// 'BytesValor' y se encapsula en el buzón. Si 'valor_HMAC' no es vacío, su longitud debe /// ser 'BytesValor'. /// </remarks> /// <param name="mensaje">Mensaje para el que se calcula el código HMAC.</param> /// <param name="valor_HMAC">Código HMAC calculado, de longitud BytesValor.</param> internal void Calcula(Buzon mensaje, Buzon valor_HMAC) { #if DEBUG Depuracion.Asevera(algoritmo != null); Depuracion.Asevera(mensaje != null); Depuracion.Asevera(mensaje.Longitud > 0); Depuracion.Asevera(valor_HMAC != null); if (valor_HMAC.Longitud > 0) { Depuracion.Asevera(valor_HMAC.Longitud == BytesValor); } #endif // byte [] retorno = algoritmo.ComputeHash(mensaje.Datos, mensaje.Inicio, mensaje.Longitud); // #if DEBUG Depuracion.Asevera(retorno.Length == BytesValor); #endif // if (valor_HMAC.Longitud == 0) { valor_HMAC.Construye(retorno); } else { Buffer.BlockCopy(retorno, 0, valor_HMAC.Datos, valor_HMAC.Inicio, BytesValor); } }
// Pone en el buzón del contador el número indicado en la posición indicada. private void PonNumeroBuzon(int numero, int inicio, Buzon destino) { destino [inicio] = (byte)(numero >> 24); destino [inicio + 1] = (byte)(numero >> 16); destino [inicio + 2] = (byte)(numero >> 8); destino [inicio + 3] = (byte)(numero); }
internal void PreparaBuzones(int longitud_paquete) { bytes_paquete = longitud_paquete; bytes_mensaje = bytes_cabecera + bytes_paquete + bytes_autentica; // if (conexion.BuzonMensaje.Longitud == 0) { conexion.BuzonMensaje.Reserva(bytes_mensaje); ConstruyeBuzones(); return; } if (conexion.BuzonMensaje.Longitud < bytes_mensaje) { AnulaBuzones(); Buzon nuevo = new Buzon(); nuevo.Reserva(bytes_mensaje); //if (conexion.paquete_entrada || // conexion.paquete_salida ) { Buzon.CopiaDatos(conexion.BuzonMensaje, nuevo, conexion.BuzonMensaje.Longitud); //} conexion.BuzonMensaje.TrasponBuzon(nuevo); ConstruyeBuzones(); return; } ReestableceBuzones(); }
internal void EnviaBillete() { buzon_billete.PonLong(0, seguridad.contador_CTR_local.NumeroSerie); buzon_indice.PonInt(0, seguridad.contador_CTR_local.NumeroMensaje); buzon_longitud.PonInt(0, buzon_mensaje.Longitud); // long billete = seguridad.GeneraBillete(0); this.buzon_numero.PonLong(0, billete); if (bytes_protocolo > 0) { Buzon.CopiaDatos(Seguridad.protocolo, buzon_protocolo); } // AutenticaCifra(); // conexion.EnviaSocket(buzon_mensaje, buzon_mensaje.Longitud); // if (bytes_protocolo > 0) { seguridad.ImprimeEnvia( buzon_billete, buzon_indice, buzon_longitud, "AES ( b1 | 'com.mazc 0.2' | hmac )"); } else { seguridad.ImprimeEnvia( buzon_billete, buzon_indice, buzon_longitud, "AES ( b2 | hmac )"); } // seguridad.contador_CTR_local.CambiaSerie(billete); seguridad.contador_CTR_remoto.CambiaSerie(billete); seguridad.contador_tiempo = DateTime.Now; }
/// <summary> /// Prepara la instancia para realizar los cálculos, estableciendo la clave de /// autenticación. /// </summary> /// <remarks> /// 'clave_SHA' puede ser de cualquier tamaño, pero el recomendado es 64 bytes. /// Cada llamada a 'Inicia' debe tener la correspondiente llamada a 'Termina' (en un 'try', /// 'finally'). /// </remarks> /// <param name="clave_SHA">Clave de autenticación, de longitud 'BytesClave'.</param> internal void Inicia(Buzon clave_SHA) { #if DEBUG Depuracion.Asevera(algoritmo == null); Depuracion.Asevera(clave_SHA != null); Depuracion.Asevera(clave_SHA.Longitud > 0); #endif // byte [] entrada; if (clave_SHA.Inicio == 0 && clave_SHA.Datos.Length == clave_SHA.Longitud) { entrada = clave_SHA.Datos; } else { entrada = new byte [clave_SHA.Longitud]; clave_SHA.TomaBinario(0, entrada); } // algoritmo = new HMACSHA256(entrada); // #if DEBUG Depuracion.Asevera(algoritmo.CanReuseTransform); Depuracion.Asevera(algoritmo.CanTransformMultipleBlocks); Depuracion.Asevera(algoritmo.HashSize == BitsValor); #endif }
internal void EstableceSecreto(Buzon secreto) { Depuracion.Asevera(Seguridad.longitud_secreto == CifradoAES.BytesClave); Depuracion.Asevera(CifradoAES.BytesClave == CalculoHMAC.BytesValor); // if (cifrado_AES_local != null) { cifrado_AES_local.Termina(); } cifrado_AES_local = new CifradoAES(); if (cifrado_AES_remoto != null) { cifrado_AES_remoto.Termina(); } cifrado_AES_remoto = new CifradoAES(); if (calculo_HMAC_local != null) { calculo_HMAC_local.Termina(); } calculo_HMAC_local = new CalculoHMAC(); if (calculo_HMAC_remoto != null) { calculo_HMAC_remoto.Termina(); } calculo_HMAC_remoto = new CalculoHMAC(); // EstableceSecreto(secreto, true, true, "clave_encripta_cliente"); EstableceSecreto(secreto, true, false, "clave_encripta_servicio"); EstableceSecreto(secreto, false, true, "clave_autentica_cliente"); EstableceSecreto(secreto, false, false, "clave_autentica_servicio"); }
internal void ActivaDeServidor(byte [] clave_privada_) { activa = true; de_servidor = true; // this.clave_privada = new Buzon(); this.clave_privada.ReservaYCopia(clave_privada_); }
protected MensajeBase(Seguridad seguridad_) { this.seguridad = seguridad_; this.conexion = seguridad_.conexion; // buzon_billete = new Buzon(); buzon_indice = new Buzon(); buzon_longitud = new Buzon(); }
/// <summary> /// Genera datos aleatorios y los escribe en el buzón. /// </summary> /// <remarks> /// El numero de bytes generados es igual a la longitud del buzón. /// </remarks> /// <param name="data">Buzón donde se dejarán los datos aleatorios.</param> internal void Genera(Buzon data) { #if DEBUG Depuracion.Asevera(algoritmo != null); Depuracion.Asevera(data != null); Depuracion.Asevera(data.Longitud > 0); #endif // algoritmo.GetBytes(data.Datos); }
// Pone en el buzon del contador la marca de serie actual. private void PonNumeroBuzon(long numero, int inicio, Buzon destino) { destino [inicio] = (byte)(numero_serie >> 56); destino [inicio + 1] = (byte)(numero_serie >> 48); destino [inicio + 2] = (byte)(numero_serie >> 40); destino [inicio + 3] = (byte)(numero_serie >> 32); destino [inicio + 4] = (byte)(numero_serie >> 24); destino [inicio + 5] = (byte)(numero_serie >> 16); destino [inicio + 6] = (byte)(numero_serie >> 8); destino [inicio + 7] = (byte)(numero_serie); }
internal void DescifraVerifica() { Cifra_AES(seguridad.cifrado_AES_remoto, seguridad.contador_CTR_remoto); // AQUI: comprobar la autenticacion seguridad.calculo_HMAC_remoto.Calcula(buzon_sensible, buzon_verifica); if (Buzon.DatosIguales(buzon_verifica, buzon_autentica)) { // AQUI: ¿que hacer???? return; } }
internal MensajeSimetrico(Seguridad seguridad_) : base(seguridad_) { buzon_autentica = new Buzon(); buzon_sensible = new Buzon(); buzon_cifrado = new Buzon(); buzon_verifica = new Buzon(); buzon_contador = new Buzon(); // PreparaPrivados(); }
protected void PreparaCabecera(Buzon buzon_mensaje) { int inicio_billete = 0; int inicio_indice = bytes_billete; int inicio_longitud = bytes_billete + bytes_indice; // buzon_mensaje.ConstruyePorcion(inicio_billete, bytes_billete, buzon_billete); buzon_mensaje.ConstruyePorcion(inicio_indice, bytes_indice, buzon_indice); buzon_mensaje.ConstruyePorcion(inicio_longitud, bytes_longitud, buzon_longitud); }
internal void Desactiva() { clave_privada = null; clave_publica = null; //if (protocolo.Longitud > 0) { // protocolo.Libera (); //} seguridad_servidor = null; contador_CTR_local = null; contador_CTR_remoto = null; mensaje_general = null; activa = false; }
private static void Imprime(ContadorCTR CTR) { Console.Write(" "); Buzon contador = new Buzon(); contador.Reserva(ContadorCTR.BytesContador); CTR.AsignaContador(contador); for (int i = 0; i < ContadorCTR.BytesContador; ++i) { Console.Write("{0:X2}", contador [i]); } Console.WriteLine(); }
protected void PreparaGrupos(Buzon buzon_mensaje, int bytes_datos) { bytes_sensible = bytes_cabecera + bytes_datos; bytes_cifrado = bytes_datos + bytes_autentica; // int inicio_sensible = 0; int inicio_cifrado = bytes_cabecera; int inicio_autentica = bytes_cabecera + bytes_datos; // buzon_mensaje.ConstruyePorcion(inicio_sensible, bytes_sensible, buzon_sensible); buzon_mensaje.ConstruyePorcion(inicio_cifrado, bytes_cifrado, buzon_cifrado); buzon_mensaje.ConstruyePorcion(inicio_autentica, bytes_autentica, buzon_autentica); }
/// <summary> /// Copia el contador en el lugar indicado. /// </summary> /// <remarks> /// El contador debe estar preprado para ser leido. Esto se hace con 'IniciaSerie', /// 'IncrementaMensaje' o 'IncrementaBloque'. Tras copiarlo (con este método) el contador /// deja de estar preparado para ser leido. /// El buzón donde se copia el contador debe ser de longitud 'BytesContador'. /// </remarks> /// <param name="destino">Buzón donde se copiará en contador.</param> internal void AsignaContador(Buzon destino) { Depuracion.Asevera(destino != null); Depuracion.Asevera(destino.Longitud == BytesContador); Depuracion.Asevera(serie_iniciada); Depuracion.Asevera(!contador_leido); // PonNumeroBuzon(numero_serie, inicio_serie, destino); PonNumeroBuzon(numero_mensaje, inicio_mensaje, destino); PonNumeroBuzon(numero_bloque, inicio_bloque, destino); //Buffer.BlockCopy (buzon_contador, 0, destino.Datos, destino.Inicio, BytesContador); // contador_leido = true; }
internal void ActivaDeCliente(byte [] clave_publica_) { activa = true; de_cliente = true; // this.clave_publica = new Buzon(); this.clave_publica.ReservaYCopia(clave_publica_); // contador_CTR_local = new ContadorCTR(); contador_CTR_remoto = new ContadorCTR(); contador_CTR_local.Inicia(); contador_CTR_remoto.Inicia(); // mensaje_general = new MensajeGeneral(this); }
internal Buzon GeneraSecreto() { Buzon secreto = new Buzon(); secreto.Reserva(Seguridad.longitud_secreto); DatosAleatorios aleatorio = new DatosAleatorios(); try { aleatorio.Inicia(); aleatorio.Genera(secreto); } finally { aleatorio.Termina(); } return(secreto); }
// Tansforma un buzón en una porción que encapsula un rango del array de bytes de esta // intancia. // El buzón a transformar, 'porcion', debe estar vacío. // La instancia no puede estar vacía ni ser una porción de otro buzón. 'inicio' y // 'longitud' deben designar un rango válido en el array de bytes. // En la instancia queda anotado que hay una porción mas creada sobre ella. internal void ConstruyePorcion(int posicion, int longitud, Buzon porcion) { #if DEBUG Depuracion.Depura(this.almacen == null, "'Buzon' vacío."); Depuracion.Depura(this.porciones < 0, "Este es porcion de otro 'Buzon'."); ValidaRango(posicion, longitud); Depuracion.Depura(porcion == null, "'porcion' nulo."); Depuracion.Depura(porcion.almacen != null, "'porcion' no vacío."); #endif // porcion.almacen = this.almacen; porcion.inicio = posicion; porcion.longitud = longitud; porcion.porciones = -1; this.porciones++; }
private void Prepara(Tipologia tipologia) { bytes_clave = 0; bytes_numero = 0; bytes_protocolo = 0; if (tipologia == Tipologia.Secreto) { bytes_clave = Seguridad.longitud_secreto; } if (tipologia == Tipologia.Inicio || tipologia == Tipologia.Billete) { bytes_numero = bytes_billete; } if (tipologia == Tipologia.Inicio) { bytes_protocolo = Seguridad.protocolo.Longitud; } bytes_datos = bytes_clave + bytes_numero + bytes_protocolo; bytes_mensaje = bytes_cabecera + bytes_datos + bytes_autentica; // buzon_mensaje = new Buzon(); buzon_clave = new Buzon(); buzon_numero = new Buzon(); buzon_protocolo = new Buzon(); // int inicio_clave = bytes_cabecera; int inicio_numero = inicio_clave + bytes_clave; int inicio_protocolo = inicio_numero + bytes_numero; // buzon_mensaje.Reserva(bytes_mensaje); PreparaCabecera(buzon_mensaje); if (bytes_clave != 0) { buzon_mensaje.ConstruyePorcion(inicio_clave, bytes_clave, buzon_clave); } if (bytes_numero != 0) { buzon_mensaje.ConstruyePorcion(inicio_numero, bytes_numero, buzon_numero); } if (bytes_protocolo != 0) { buzon_mensaje.ConstruyePorcion(inicio_protocolo, bytes_protocolo, buzon_protocolo); } PreparaGrupos(buzon_mensaje, bytes_datos); }
internal void RecibeBillete() { conexion.RecibeSocket(buzon_mensaje, 0, buzon_mensaje.Longitud); // if (bytes_protocolo > 0) { seguridad.ImprimeRecibe( buzon_billete, buzon_indice, buzon_longitud, "AES ( b1 | 'com.mazc 0.2' | hmac )"); } else { seguridad.ImprimeRecibe( buzon_billete, buzon_indice, buzon_longitud, "AES ( b2 | hmac )"); } // // se valida el mensaje if (//buzon_billete .TomaLong (0) == 0 || buzon_indice.TomaInt(0) != 0 || buzon_longitud.TomaInt(0) != buzon_mensaje.Longitud) { // ???? return; } // DescifraVerifica(); // if (bytes_protocolo > 0) { if (!Buzon.DatosIguales(buzon_protocolo, Seguridad.protocolo)) { // ???? return; } } // long billete = buzon_numero.TomaLong(0); // seguridad.contador_CTR_local.CambiaSerie(billete); seguridad.contador_CTR_remoto.CambiaSerie(billete); seguridad.contador_tiempo = DateTime.Now; }
// Anula una porción de esta instancia, dejandola vacía. // El buzón anulado ('porcion') debe ser una porción previamente construida sobre esta // instancia. // En la instancia queda anotado que hay una porción menos creada sobre ella. internal void AnulaPorcion(Buzon porcion) { #if DEBUG Depuracion.Depura(this.almacen == null, "'Buzon' vacío."); Depuracion.Depura(this.porciones < 0, "Este es porcion de otro 'Buzon'."); Depuracion.Depura(this.porciones == 0, "Este no tiene porciones."); Depuracion.Depura(porcion == null, "'porcion' nulo"); Depuracion.Depura(porcion.almacen == null, "'porcion' vacío"); Depuracion.Depura(porcion.porciones >= 0, "'porcion' no es un porcion'"); Depuracion.Depura(porcion.almacen != this.almacen, "'porcion' no es porcion de este"); #endif // porcion.almacen = null; porcion.inicio = 0; porcion.longitud = 0; porcion.porciones = 0; this.porciones--; }
internal void EnviaSecreto() { buzon_billete.PonLong(0, seguridad.contador_CTR_local.NumeroSerie); buzon_indice.PonInt(0, seguridad.contador_CTR_local.NumeroMensaje); buzon_longitud.PonInt(0, buzon_mensaje.Longitud); // Buzon secreto = seguridad.GeneraSecreto(); Buzon.CopiaDatos(secreto, this.buzon_clave); // AutenticaCifra(); // conexion.EnviaSocket(buzon_mensaje, buzon_mensaje.Longitud); // seguridad.ImprimeEnvia( buzon_billete, buzon_indice, buzon_longitud, "AES ( S2 | hmac )"); // seguridad.EstableceSecreto(secreto); }
// prepara los buzones private void Prepara() { bytes_protocolo = Seguridad.protocolo.Longitud; bytes_texto = bytes_secreto + bytes_protocolo; // buzon_texto = new Buzon(); buzon_secreto = new Buzon(); buzon_protocolo = new Buzon(); // buzon_texto.Reserva(bytes_texto); buzon_texto.ConstruyePorcion(0, bytes_secreto, buzon_secreto); buzon_texto.ConstruyePorcion(bytes_secreto, bytes_protocolo, buzon_protocolo); // buzon_mensaje = new Buzon(); buzon_cifrado = new Buzon(); // buzon_mensaje.Reserva(bytes_mensaje); PreparaCabecera(buzon_mensaje); buzon_mensaje.ConstruyePorcion(bytes_cabecera, bytes_cifrado, buzon_cifrado); }
// Traslada el array de bytes encapsulado desde el buzón indicado, hasta esta instancia. // Esta instancia se vacía antes del traslado. 'origen' queda vacío tras el traslado. // Ni esta instancia ni 'origen' pueden ser porciones, ni pueden tener porciones construidas // sobre ellos. internal void TrasponBuzon(Buzon origen) { #if DEBUG // admite buzon vacío y no vacío Depuracion.Depura(this.porciones < 0, "Este es porción de otro 'Buzon'."); Depuracion.Depura(this.porciones > 0, "Quedan porciones de este 'Buzon'."); Depuracion.Depura(origen == null, "'origen' nulo"); Depuracion.Depura(origen.almacen == null, "'origen' vacío."); Depuracion.Depura(origen.porciones < 0, "'origen' es porcion de otro 'Buzon'."); Depuracion.Depura(origen.porciones > 0, "Quedan porciones de 'origen'."); #endif // this.almacen = origen.almacen; this.inicio = origen.inicio; this.longitud = origen.longitud; this.porciones = origen.porciones; origen.almacen = null; origen.inicio = 0; origen.longitud = 0; origen.porciones = 0; }
// Copia el array de bytes de un buzón en otro buzón. // Los buzones deben ser de la misma longitud y no puede ser vacíos. // Los buzones puede ser porciones (uno o los dos). En tal caso se copia el rango que // especifican. internal static void CopiaDatos(Buzon origen, Buzon destino) { #if DEBUG Depuracion.Depura(origen == null, "'origen' nulo"); Depuracion.Depura(destino == null, "'destino' nulo"); Depuracion.Depura(origen.almacen == null, "'origen' vacío"); Depuracion.Depura(destino.almacen == null, "'destino' vacío"); Depuracion.Depura(origen.longitud != destino.longitud, "'origen' y 'destino' de longitudes distintas"); #endif // int indice_origen = origen.inicio; int indice_destino = destino.inicio; int longitud = origen.longitud; while (longitud > 0) { destino.almacen [indice_destino] = origen.almacen [indice_origen]; indice_origen++; indice_destino++; longitud--; } }
// Copia una parte del array de bytes de un buzón en otro buzón. // El rango de bytes a copiar, tanto en 'origen' como en 'destino', es de 0 a 'longitud_'-1. // El rango debe ser válido en ambos buzones. // Los buzones puede ser porciones (uno o los dos). En tal caso, el rango a copiar se toma // dentro del rango de la porción. internal static void CopiaDatos(Buzon origen, Buzon destino, int longitud_) { #if DEBUG Depuracion.Depura(origen == null, "'origen' nulo"); Depuracion.Depura(destino == null, "'destino' nulo"); Depuracion.Depura(origen.almacen == null, "'origen' vacío"); Depuracion.Depura(destino.almacen == null, "'destino' vacío"); origen.ValidaRango(0, longitud_); destino.ValidaRango(0, longitud_); #endif // int indice_origen = origen.inicio; int indice_destino = destino.inicio; while (longitud_ > 0) { destino.almacen [indice_destino] = origen.almacen [indice_origen]; indice_origen++; indice_destino++; longitud_--; } }