|
Si deseas hacer un intercambio de links con DotNetcr, escríbenos aquí
|
 |
Recibe las actualizaciones vía RSS
|
|
|
Encriptar textos en SQL |
|
El SQL tiene por defecto diversos encriptadores, también herramientas como .Net y otras más, pero las más seguras no tiene el modo de desencriptar, en este ejemplo vamos a fabricar un encriptador al cual podamos desencriptar.
|
|
|
| Categorías : SQL Server |
| Autor : h@nz |
Fecha : 9/17/2006 |
Visitas : 16000 |
Voto : 4.00 |
|
Mucho se ha escrito sobre este tema, tanto que ya no es necesario descubrir la rueda para encriptar sobretodo contraseñas (o cualquier otro dato), desde algoritmos sencillos (como sumar a cada valor ascii de cada caracter un valor cualquiera) hasta los mas complejos (como rijndael y otros) existen en todos lados a nuestra libre disposición.
El propio SQL (en ingles se pronuncia ES-KIU-EL y no SICUEL como dicen algunos) Server propone una forma de encriptar los datos, si usamos PwdEncrypt('Mi contraseña') obtendremos algo como esto:
0x0100A36C176B9D8F41B774C25... este dato de tipo varbynary no esta nada mal, el problema es que ni el propio SQL Server lo puede desencriptar (o al menos asi parece). Si usamos PwdCompare('Mi contraseña', 'el binario con el que comparar') lo único que conseguiremos será comparar ambas cadenas, cosa que tampoco esta mal...
Nunca les ha pasado que un usuario final se olvida su contraseña y llama al Dpto. de Sistemas (Se supone que nuestro Dpto.) pidiendo que les digan su clave????, ah! pero eso si! en sus requerimientos piden que sus claves sean encriptadas para que nadie sepan que son. Bueno, hace poco hice este pequeño
script que permite encriptar una cadena de hasta 20 caracteres en otra de 50 caracteres. A ver si se animan a copiar y pegar... la explicación esta al final.
CREATE PROCEDURE usp_Encriptar(@texto varchar(20), @clave varchar(50)
output)
with encryption
AS
-- Una cadena de texto cualquiera que sirve para cambiar el valor ingresado
declare @key varchar(50)
-- Contadores para las repeticiones
declare @i integer, @j integer
-- Apoyo para conversiones
declare @aux integer
-- Valor Ascii de cada caracter que se extrae del dato ingresado
declare @vAsc integer
-- Apoyo para extraer caracteres de la cadena
declare @posIni integer
-- Contendra el valor binario de cada caracter del texto enviado
declare @chrBin varchar(8)
-- Auxiliar para crear la cadena encriptada
declare @chrAux varchar(8)
-- Contendra la cadena binaria completa del texto enviado
declare @strBin varchar(320)
-- La cadena binaria pero invertida por cada caracter
declare @strInv varchar(320)
-- Para armar el byte de la cadena encriptada (1 caracter = 1 byte = 8 bits)
declare @ci1 char(8), @ci2 char(8)
set @key = 'ColoqueAquiSuPropiaClave'
--1. Convertir el texto enviado en una cadena de binarios
set @i = 1
set @vAsc = 0
set @strBin = ''
while @i <= len(ltrim(rtrim(@texto)))
begin
set @chrBin = ''
set @vAsc = ascii(substring(ltrim(rtrim(@texto)), @i, 1))
while @vAsc >= 2
begin
set @chrBin = ltrim(rtrim(str(@vAsc % 2))) + ltrim(rtrim(@chrBin))
set @vAsc = @vAsc / 2
end
set @chrBin = ltrim(rtrim(str(@vAsc))) + ltrim(rtrim(@chrBin))
while len(ltrim(rtrim(@chrBin))) < 8
set @chrBin = '0' + ltrim(rtrim(@chrBin))
set @strBin = ltrim(rtrim(@strBin)) + ltrim(rtrim(@chrBin))
set @i = @i + 1
end
--2. Invertir la cadena binaria por cada caracter
set @i = 1
set @posIni = 1
set @strInv = ''
set @strBin = reverse(ltrim(rtrim(@strBin)))
while @i <= len(ltrim(rtrim(@texto)))
begin
set @chrBin = ''
set @chrBin = substring(ltrim(rtrim(@strBin)), @posIni, 8)
set @chrBin = reverse(ltrim(rtrim(@chrBin)))
set @strInv = ltrim(rtrim(@strInv)) + ltrim(rtrim(@chrBin))
set @posIni = @posIni + 8
set @i = @i + 1
end
--3. Crear la cadena binaria del encriptado
set @i = 1
set @j = 1
set @posIni = 1
set @vAsc = 0
set @strBin = ''
while @i <= len(ltrim(rtrim(@texto)))
begin
set @chrBin = ''
set @chrBin = substring(ltrim(rtrim(@strInv)), @posIni, 8)
set @ci1 = substring(ltrim(rtrim(@chrBin)), 1, 4)
set @ci2 = substring(ltrim(rtrim(@chrBin)), 5, 4)
--Descomponer en ascii la llave (@key)
set @chrAux = ''
set @vAsc = ascii(substring(ltrim(rtrim(@key)), @j, 1))
while @vAsc >= 2
begin
set @chrAux = ltrim(rtrim(str(@vAsc % 2))) + ltrim(rtrim(@chrAux))
set @vAsc = @vAsc / 2
end
set @chrAux = ltrim(rtrim(str(@vAsc))) + ltrim(rtrim(@chrAux))
while len(ltrim(rtrim(@chrAux))) < 8
set @chrAux = '0' + ltrim(rtrim(@chrAux))
--Fin descomponer la llave
set @ci1 = ltrim(rtrim(@ci1)) + substring(ltrim(rtrim(@chrAux)), 1, 4)
set @ci2 = ltrim(rtrim(@ci2)) + substring(ltrim(rtrim(@chrAux)), 5, 4)
set @strBin = ltrim(rtrim(@strBin)) + ltrim(rtrim(@ci1)) + ltrim(rtrim(@ci2))
set @posIni = @posIni + 8
set @i = @i + 1
end
--4. Convertir la cadena binaria en una cadena de caracteres
set @i = 1
set @posIni = 1
set @chrBin = ''
set @strInv = ''
set @strInv = ltrim(rtrim(@strBin))
set @strBin = ''
while @i <= len(ltrim(rtrim(@strInv))) / 8
begin
set @j = 0
set @aux = 1
set @vAsc = 0
set @chrBin = substring(ltrim(rtrim(@strInv)), @posIni, 8)
while @j <= (len(ltrim(rtrim(@chrBin))) - 1)
begin
set @vAsc = @vAsc + (cast(substring(ltrim(rtrim(@chrBin)), len(ltrim(rtrim(@chrBin))) - @j, 1) as int) * @aux)
set @aux = @aux * 2
set @j = @j + 1
end
set @strBin = ltrim(rtrim(@strBin)) + ltrim(rtrim(char(@vAsc)))
set @posIni = @posIni + 8
set @i = @i + 1
end
--5. Generar la cadena de 40 caracteres
set @i = len(ltrim(rtrim(@strBin)))
set @strInv = ''
while @i < 40
begin
set @vAsc = 0
while (@vAsc < 33) or (@vAsc = 39)
set @vAsc = round(rand() * 255,0)
set @strInv = ltrim(rtrim(@strInv)) + ltrim(rtrim(char(@vAsc)))
set @i = @i + 1
end
set @strBin = ltrim(rtrim(@strInv)) + ltrim(rtrim(@strBin))
--6. Agregar los flags de longitud y completar los 50 caracteres
set @aux = len(ltrim(rtrim(@texto)))
if @aux < 10
begin
set @i = 0
set @j = @aux
end
else
begin
set @i = substring(ltrim(rtrim(@aux)), 1, 1)
set @j = substring(ltrim(rtrim(@aux)), 2, 1)
end
set @aux = 1
set @chrBin = ''
set @chrAux = ''
while @aux <= 5
begin
set @vAsc = 0
while (@vAsc < 33) or (@vAsc = 39)
set @vAsc = round(rand() * 255,0)
if @aux = 3
set @chrBin = ltrim(rtrim(@chrBin)) + ltrim(rtrim(str(@i)))
else
set @chrBin = ltrim(rtrim(@chrBin)) + ltrim(rtrim(char(@vAsc)))
set @vAsc = 0
while (@vAsc < 33) or (@vAsc = 39)
set @vAsc = round(rand() * 255,0)
if @aux = 3
set @chrAux = ltrim(rtrim(@chrAux)) + ltrim(rtrim(str(@j)))
else
set @chrAux = ltrim(rtrim(@chrAux)) + ltrim(rtrim(char(@vAsc)))
set @aux = @aux + 1
end
--7. Devolver el resultado
set @clave = ltrim(rtrim(@chrBin)) + ltrim(rtrim(@strBin)) +
ltrim(rtrim(@chrAux))
return 0
go
Explicación:
Si por ejemplo escribo Hancito, el resultado será una cadena mas o menos como esta:
Œê0ÉâE9¶ÀÉœ_bŒŸRÓuÊtžôû‡uÊAœšdótCd“d3dãdDƒy/7*a
Bien, esa cadena tiene caracteres agregados por las puras... el encriptado original consta del doble de caracteres del texto enviado, osea 14 caracteres en nuestro ejemplo, los otros 36 estan por las puras, solo para despistar al enemigo. El truco esta aquí:
Œê 0 ÉâE9¶ÀÉœ_bŒŸRÓuÊtžôû‡uÊAœš dótCd“d3dãdDƒ y/ 7 *a
El tercer y 48vo. caracter contiene la informacion de la longitud original del texto (Hancito tiene 07 caracteres) y solo la parte que esta en negrita (dótCd“d3dãdDƒ) tiene el encriptado. Si alguien intenta desencriptarlo a la fuerza, empezará por delante y nunca descubrirá el texto (bueno, eso de nunca es un decir), esa cadena delantera es aleatoria.
La instruccion with encryption permite encriptar todo el Stored Procedure en SQL, eso significa que ninguna persona lo podrá leer, ni siquiera quien lo creo, es decir que si pierden las fuentes, ya fueron. No se olviden de cambiar 'ColoqueAquiSuPropiaClave' por una clave de hasta 25 caracteres cualquiera, respetando las reglas para la creación de passwords que todos conocemos (Despues escribiré sobre eso por si acaso alguien no sabe)
Bueno, la discusión sobre este tema es larga, no pretendo que sea el mejor script para encriptar textos, pero me parece una buena alternativa. El script para desencriptar lo colocaré aparte porque juntos ocuparían mas espacio (por cierto ya ocupe bastante).
|
Por Anónimo - Fecha: 2006/10/16 01:29 PM
Hola me gustaria saber .. como puedo ver el resultado de tu script
Por Anónimo - Fecha: 2006/10/16 01:30 PM
Hola Me gustaria saber como mostar el resultado de tu script porfavor si puedes darme la respuesta al correo roco_666_428@hotmail.com porfavor ..
Por h@nz - Fecha: 2006/10/19 06:39 PM
Hola, para ver el resultado del script en el Analizador de consultas pueden utilizar la siguiente instrucción:
declare @resultado varchar(50)
exec usp_Encriptar ''miPalabraSecreta'', @resultado output
print @resultado
miPalabraSecreta debe ser un texto de no mas de 20 caracteres.
Saludos....
Por h@nz - Fecha: 2006/10/19 06:41 PM
bueno, debe ser solo con una comilla simple, por error me salieron dos en el ejemplo... intentenlo...
nos vemos...
Por Anónimo - Fecha: 2006/11/03 10:44 AM
Excelente trabajo, estaba viendo unos ejemplos de diferentes algoritmos en .Net y esto es lo que buscaba, Danko Sher.
Por Anónimo - Fecha: 2006/11/15 01:08 PM
Y donde se desencripta?
Por Anónimo - Fecha: 2006/11/15 01:18 PM
Se hablo desde el principio de un algoritmo con la propiedad para encriptar y desencriptar, por favor como se haria para desencriptar?
Por h@nz - Fecha: 2006/11/16 08:37 AM
La parte de la desencriptación se encuentra en un artículo aparte, si lo hubiera puesto en uno solo sería muy largo... ahi les va el link para el desencriptado:
http://www.dotnetcr.com/Libreria.aspx?art=102&tag=Encriptar-textos-en-SQL-Segunda-Parte
Saludos...
Por Anónimo - Fecha: 2006/11/16 10:46 AM
Un millon de gracias, este fue un buen trabajo.
Dios los recompensara.
Saludos
Por Anónimo - Fecha: 2006/11/27 08:42 AM
Me parecio bastante interesante tu articulo
Por Anónimo - Fecha: 2007/03/25 11:33 AM
un muy buena explicacion tu si que sabes!!!
Por Anónimo - Fecha: 2007/08/15 12:44 PM
Buen algoritmo... Una pregunta.. Estoy utilizando Visual Basic 6.0.. Esta funcion la hago en vusual basic 6.0 o en SQL.. Y si la hago en SQL Como la utilizo para almacenar la clave desencriptada????
Por Anónimo - Fecha: 2008/03/24 03:38 PM
si eso esta muy bien
Por Anónimo - Fecha: 2010/06/25 10:55 AM
pueden volver a postear la segunda parte de este tema??
Por Anónimo - Fecha: 2010/07/07 12:51 AM
sta chvr tu algoritmo...pero...el script para desencriptar¿?¿?..pueds ponerlo o poner el link d dond sta¿?¿?
|
|

carlosm

r

darionet

Dark_Fang

dominio

viferfer
PER |
233 |
MEX |
226 |
CRI |
180 |
COL |
114 |
ESP |
99 |
ARG |
82 |
|