Red de conocimiento informático - Material del sitio web - Cómo cifrar software de mensajería instantánea usando lenguaje java

Cómo cifrar software de mensajería instantánea usando lenguaje java

1. La idea básica del cifrado de software Java

El autor considera la protección del software de aplicaciones desde dos aspectos: el primero es evitar la piratería del software y el segundo es evitar que los competidores lo descompilen. software, es decir, impidiendo la ingeniería inversa del software.

1. Detener la piratería

Cuando el software se esté ejecutando, juzgará la legalidad de su propia existencia. Si cree que su existencia y funcionamiento son autorizados y legales, se ejecutará. ; de lo contrario, se dará por terminada la operación. De esta forma, incluso si el software se puede copiar a voluntad, mientras los usuarios pirateados no tengan la información de autorización correspondiente, no podrán utilizar el software.

2. Prevenir la descompilación

Cifrar archivos de clase compilados y descifrarlos en tiempo de ejecución. Los descifradores no pueden descompilar software.

2. El proceso general de cifrado de software Java

Para proteger el software desarrollado en lenguaje Java, diseñamos e implementamos un algoritmo de cifrado práctico de alta resistencia. A continuación, el software Java que debe protegerse se denomina "programa de protección" y el software que cifra el "programa de protección" se denomina "programa de cifrado". El proceso de protección de cifrado de software se muestra en la Figura 1.

En tercer lugar, análisis y diseño del algoritmo de cifrado

1. Diseño del extractor de información del usuario

Para evitar que los usuarios publiquen números de serie, lo que resulta en "publicar". Una vez, publica en cualquier lugar el problema de piratería "visible", extrae la única información relacionada con el hardware en la máquina del usuario: el número de serie de la partición C del disco duro de la computadora del usuario, y requiere que el usuario devuelva esta información junto con el nombre de usuario. Luego, el "generador de números de serie" genera un número de serie de registro de software único y legal basado en la información devuelta por el usuario y se lo envía al usuario. El usuario puede usar este número para registrarse y usar el software.

Este extractor de información se implementa como un subprograma independiente utilizando el ensamblador Winclows 32. El código del programa se muestra en la Figura 2.

2. Diseño de generador de números de serie y función de juicio de legalidad de números de serie.

El generador de números de serie y la función de evaluación de la validez del número de serie utilizan el algoritmo de cifrado RSA. En el generador de números de serie, la clave privada se utiliza para cifrar la información devuelta por el usuario (número de serie del disco duro, nombre de usuario) para obtener el número de serie de registro correspondiente; la clave privada se utiliza para descifrar el número de serie de registro ingresado por el usuario; usuario en la función de juicio de legalidad del número de serie y luego compárelo con (número de serie del disco duro, nombre de usuario). Si es consistente, llame al cargador de programas para descifrar otras partes del programa y cárguelas en la memoria, inicialice el entorno de eliminación y ejecute el cuerpo del programa;

La implementación del algoritmo de cifrado RSA requiere el uso de una biblioteca de operaciones de gran número. Usamos la biblioteca de números grandes MIRACL para implementar la operación RSA. El código principal del generador de números de serie es el siguiente:

Char szlnputString[]= "Una cadena compuesta por código de máquina y nombre de usuario";

char szSerial[256]=[ 0] ; //Se utiliza para almacenar el código de registro generado.

bign, d, c, m; //Tipos de números grandes en MIRACL

MIP→IBASE = 16 //En 16 modo básico

n = MLR var(0); //Inicializa un gran número

d = mirvar(0);

c = mirvar(0); //C almacena un gran número de caracteres de entrada. cadena.

m = ml RVA(o);

bytes a big(len, szlnputString, c

//Convierte la cadena de entrada en grande); El número se almacena en la variable c.

Cinstr(n, "módulo expresado como una cadena"); //Inicializa el módulo

Cinstr(d, "clave pública expresada como una cadena") ://Inicializa el clave pública.

powmod(c, d, n, m); //Calcular m = cdmod n

cotstr(m, SZ serial); //La cadena binaria 16 de m es la código de registro.

El código principal de la función de detección de validez del número de serie es el siguiente:

Char szlnputStringL]= "Una cadena compuesta por código de máquina y nombre de usuario";

Char szSerial[256]= "Número de serie ingresado por el usuario"

bign, e, c, m; //Escriba números grandes en MIRACL

MIP→IBASE = 16; // En modo básico 16

cinstr(m, SZ serial); //Convierte el número de serie de 16 a un número grande.

Cinstr(n, "Forma de cadena del módulo n"); //Inicializar módulo n

Cinstr(e, "Clave pública en forma de cadena");/ /Inicializar clave pública

if compare(m,n)= =-1)//m lt;n antes del descifrado.

{

powmod(masculino, femenino, masculino, femenino); //Calcular m=me mod n

big_to _bytes(0, c, szSerial, 0); //Convertir a cadena

Devuelve lstrcmp(szlnputString, SZ serial);

}

3. Diseño de relación de acoplamiento fuerte

Si el proceso que se muestra en la Figura 3 solo se usa para la función de detección de validez del número de serie:

El descifrador puede usar los siguientes métodos para atacar:

(1) Modificar el Comando de retorno "Sentencia" "Subfunción de legalidad" para que siempre devuelva el valor correcto para que el software pueda instalarse/utilizarse con cualquier número de serie.

(2) Modifique la instrucción de salto después del juicio para que el programa siempre salte a la rama correcta. El efecto es el mismo que el anterior.

(3) Ejecute una instrucción de salto antes de la "subfunción de legalidad del juez" para omitir el juicio y saltar directamente a la rama de "ejecución normal", de modo que pueda instalarla/usarla sin ingresar al serial. número.

Para evitar los métodos de ataque anteriores, el autor ha agregado el requisito de un "acoplamiento fuerte" entre la función de detección de legalidad del número de serie y otras partes del programa (es decir, mejorando su correlación con otras partes). del programa y volviéndose inseparable de todo el programa) Una vez que se modifica parte del mismo, el programa no funcionará correctamente) (ver Figura 1), y se configura una "función de detección de integridad" para determinar si el código relevante ha sido modificado . Por supuesto, por la misma razón, la "función de verificación de integridad" también debe tener una relación "fuertemente acoplada" con otras partes del programa.

Las relaciones de acoplamiento fuertes se establecen de las siguientes maneras:

Las funciones de acceso aleatorio en otras partes del programa (como la función A) requieren "función de detección de validez del número de serie" y "función de integridad". Función de detección "acoplamiento fuerte. Al llamar, seleccione aleatoriamente un número de serie incorrecto o el número de serie ingresado por el usuario, y seleccione el código de función normal o el código de función incorrecto en A según el resultado devuelto. El proceso se muestra en la Figura 4.

Después de esta mejora, si el cracker se rompe al modificar el código, el programa se cerrará porque falla la "verificación de integridad"; si se utiliza SMC y otras tecnologías para evitar la "función de juicio de legalidad del número de serie", el programa Cuando el número sea correcto, saltará directamente a la entrada de ejecución. El programa saldrá debido a la falla de las llamadas de acoplamiento aleatorio en operaciones posteriores. Para romper el software, el cracker tendría que realizar un seguimiento de todas las funciones llamadas a través del acoplamiento, lo que obviamente es una tarea difícil.

4. Diseño de la función de detección de integridad.

Utilizamos el algoritmo CRC para calcular el código de verificación del archivo que necesita detección de integridad y utilizamos la clave pública del algoritmo de cifrado RSA (diferente del par de clave pública/clave privada en la legitimidad del número de serie). detección) para realizarlo Cifrado y almacenado en un archivo específico. Al detectar, primero usamos el algoritmo CRC para regenerar.

Utilice la clave privada para descifrar el código de verificación del archivo de detección de integridad, compare los dos y, si son iguales, ejecútelo normalmente; de ​​lo contrario, salga;

5. Diseño del cargador de programas

A diferencia de los programas compilados en código de máquina, los programas Java sólo pueden ser interpretados y ejecutados por la máquina virtual Java, por lo que el trabajo del cargador de programas incluye: Inicialice la máquina virtual Java; descifre el archivo de clase que se ejecuta actualmente en la memoria; deje que el archivo de clase c: descifrado se ejecute en la máquina virtual.

Descifre otro archivo de clase si es necesario. La Figura 5 es el código utilizado para inicializar la JVM:

Lo anterior presenta el método de protección de cifrado que diseñamos para el software Java, que utiliza una variedad de tecnologías de cifrado para proporcionar una alta resistencia anti-craqueo utilizando protección de software pura; tecnología, Bajo costo. Probado por el autor en plataformas de la serie Windows, funciona de manera estable y tiene buenos resultados.

Durante el proceso de investigación y desarrollo, también resumimos algunas experiencias en software de protección de cifrado:

1. El código clave y los datos deben cifrarse estáticamente y luego descifrarse dinámicamente. La tecnología anti-seguimiento/depuración debe usarse en combinación con la plataforma de trabajo específica;

2. Aproveche al máximo las funciones del sistema, como el uso de archivos DLL o controladores en Windows, para obtener el mayor enriquecimiento y restricciones y aprovechar al máximo el sistema Varias funciones;

3. Si es posible, los códigos clave deben almacenarse en un lugar que no se pueda copiar.

4. asociarse con información del usuario, como código de máquina, para evitar que Salt vuelva a circular;

5. La racionalidad del proceso de cifrado es más importante que la solidez del algoritmo de cifrado en sí.