MD5 Hashing en Delphi 2009
unicode delphi-2009 (7)
¿Acaso estás lanzando una cadena genérica (que en Delphi 2009 es un UnicodeString) a un PAnsiChar y pasando eso a la función hash? Eso no funcionará. Primero debes convertir la cadena en un AnsiString y luego lanzarlo a PAnsiChar, a la:
PAnsiChar(AnsiString(''123456''))
Además, intente utilizar RawByteString en lugar de AnsiString como se sugiere dmajkic. Evite UTF8String ya que no es un AnsiString y cualquier carácter fuera del rango ASCII (0..127) podría ser reinterpretado en caracteres multibyte.
En borland delphi 7 e incluso en delphi 2007 todo funcionó, pero en delphi 2009 ¡simplemente devuelve el hash incorrecto!
Yo uso el script wcrypt2 ( http://pastebin.com/m2f015cfd )
Sólo echar un vistazo:
cadena: "123456"
picadillo:
Delphi 7: "e10adc3949ba59abbe56e057f20f883e" - hash real.
Delphi 2007: "e10adc3949ba59abbe56e057f20f883e" - hash real también.
Y ... Delphi 2009: "5fa285e1bebe0a6623e33afc04a1fbd5" - ¿WTF?
He probado muchos scripts de md5, pero Delphi 2009 hace lo mismo con todos. ¿Alguna ayuda? Gracias.
¿Ha comprobado que su biblioteca se ha actualizado correctamente para D2009 y la unicodificación? Tengo dudas de que el mismo código haga D7 / D2007 y D2009 para este tipo de cosas.
Su biblioteca no tiene conocimiento de Unicode. Simplemente pasarle un AnsiString no será suficiente porque probablemente usa cadenas internas para almacenar datos.
Puede intentar actualizar esa biblioteca, esperar a que el autor la actualice o simplemente usar el MessageDigest_5.pas que se envía con Delphi 2009. Está en la carpeta source / Win32 / soap / wsdlimporter , que deberá agregar a su camino, o explícitamente incluirlo en su proyecto.
Aquí hay un código de muestra que lo usa en Delphi 2009:
uses Types, MessageDigest_5;
procedure TForm16.Edit1Change(Sender: TObject);
var
MD5: IMD5;
begin
MD5 := GetMD5;
MD5.Init;
MD5.Update(TByteDynArray(RawByteString(Edit1.Text)), Length(Edit1.Text));
Edit2.Text := LowerCase(MD5.AsString);
end;
Y tú estás en el negocio:
MD5 (123456) = e10adc3949ba59abbe56e057f20f883e
Podría envolverlo en una llamada a función simple si quisiera. Es importante que selecciones un RawByteString antes de enviarlo a un TByteDynArray, ya que el lanzamiento RawByteString elimina todos los caracteres Unicode adicionales. Concedido si la edición contiene caracteres Unicode, entonces podrías terminar con datos incorrectos.
Tenga en cuenta que GetMD5 devuelve una interfaz, por lo que se hace referencia a la referencia, etc.
¡Feliz Navidad!
En la respuesta de Jim:
si cambiamos
MD5.Update (TByteDynArray (RawByteString (Edit1.Text)), Length (Edit1.Text));
a
MD5.Update (TByteDynArray (RawByteString (Edit1.Text)), Length (RawByteString (Edit1.Text)));
apoyará mejor mientras que los caracteres chinos existen.
Antes de que alguien pueda comentar los algoritmos de hashing, es útil que al menos tengan una comprensión fundamental de los conceptos y principios subyacentes. Todas las respuestas hasta el momento que se han centrado en el encasillado sin fin son completamente exageradas, pero aún peor, darán como resultado resultados poco confiables si se codifica una cadena Unicode.
Lo primero que debe entender es que los algoritmos de cifrado y hash funcionan a nivel de byte. Eso significa que no les importa lo que has hashing o encriptado. Puede hash enteros, caracteres, ASCII simple, unicode completo, bytes, longwords, etc. etc. Al algoritmo no le importa.
Al trabajar con cadenas, lo ÚNICO que debe asegurarse es que la función interna de su biblioteca de hash retorne un AnsiString en la función que escupe el hash resultante. Eso es. Eso es todo lo que importa.
Su código real para SU proyecto puede (y debería) basarse en la entrada de cadena normal, que se correlaciona con unicodestring en Delphi 2009. No debe convertir nada a ansistring o rawbytestring. De este modo, inmediatamente crea un hash roto si el usuario intenta hacer un hash fuera del alcance del juego de caracteres ANSI. Y en el mundo de hashing, un hash roto no es confiable ni inseguro.
Si tiene wcrypt2.pas
, use esta función.
function md5ansi(const Input: AnsiString): AnsiString;
var
hCryptProvider: HCRYPTPROV;
hHash: HCRYPTHASH;
bHash: array[0..$7f] of Byte;
dwHashBytes: Cardinal;
pbContent: PByte;
i: Integer;
begin
dwHashBytes := 16;
pbContent := Pointer(PAnsiChar(Input));
Result := '''';
if CryptAcquireContext(@hCryptProvider, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT or CRYPT_MACHINE_KEYSET) then
begin
if CryptCreateHash(hCryptProvider, CALG_MD5, 0, 0, @hHash) then
begin
if CryptHashData(hHash, pbContent, Length(Input) * sizeof(AnsiChar), 0) then
begin
if CryptGetHashParam(hHash, HP_HASHVAL, @bHash[0], @dwHashBytes, 0) then
begin
for i := 0 to dwHashBytes - 1 do
begin
Result := Result + AnsiString(Format(''%.2x'', [bHash[i]]));
end;
end;
end;
CryptDestroyHash(hHash);
end;
CryptReleaseContext(hCryptProvider, 0);
end;
Result := AnsiString(AnsiLowerCase(String(Result)));
end;
Es obvio que su lib no está habilitado para Unicode.
Convierta su cadena a AnsiString o RawByteString o UTF8String declarando temp AnsiString y asigne su cadena uniode a ella.
Tenga en cuenta que si está utilizando caracteres específicos de Unicode que no se pueden traducir a una sola página de códigos, debe convertir su cadena a UTF8.
Luego llame a MD5 (PAnsiChar (YourTempString)).
Compruebe que su lib puede tener declaraciones PWideChar o UNICODE, para omitir esto.