Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kdo je autorem výstavy obrazových fotografií „Očima Hanse Christiana Andersena“?

V dnešní soutěži hrajeme o:



Přepis šifrování z .NETu do javy

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

Přepis šifrování z .NETu do javy

Autor: Kle@ ♂

14:06:40 11.03.2015

Dobrý den,

potřeboval bych přepsat šifrovací algoritmus, který je napsán v .NETu (tedy úplně prapůvodně je v PowerBuilderu) do javy.

V C# to vypadá takto:

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptAcquireContext(out IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptCreateHash(IntPtr hProv, ALG_ID Algid, IntPtr hKey, uint dwFlags, out IntPtr phHash);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptHashData(IntPtr hHash, byte[] pbData, int dwDataLen, uint dwFlags);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDeriveKey(IntPtr hProv, ALG_ID Algid, IntPtr hBaseData, uint dwFlags, out IntPtr phKey);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, int Final, uint dwFlags, byte[] pbData, out uint pdwDataLen, uint dwBufLen);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDestroyHash(IntPtr hHash);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecrypt(IntPtr hKey, IntPtr hHash, [MarshalAs(UnmanagedType.Bool)] bool Final, uint dwFlags, byte[] pbData, ref int pdwDataLen);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDestroyKey(IntPtr hKey);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);

public const uint PROV_RSA_FULL = 0x00000001;//1;
public const uint CRYPT_VERIFYCONTEXT = 0xF0000000; //; 4026531840;

public enum ALG_ID
{
CALG_MD5 = 0x00008003,//32771,
CALG_RC2 = 26114,
CALG_RC4 = 26625
}
const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0";

public static string GetHashPassword(string str, string Password)
{
IntPtr hCryptProv;
IntPtr hKey;
IntPtr hHash;

System.Text.ASCIIEncoding _encoding = new System.Text.ASCIIEncoding();
byte[] BPassword = _encoding.GetBytes(Password);

CryptAcquireContext(out hCryptProv, null, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT );

if (!CryptCreateHash(hCryptProv, ALG_ID.CALG_MD5, IntPtr.Zero, 0, out hHash))
return "";

if (!CryptHashData(hHash, BPassword, BPassword.Length, 0))
return "";

if (!CryptDeriveKey(hCryptProv, ALG_ID.CALG_RC4, hHash, 0, out hKey))
return "";
uint DataLen = Convert.ToUInt32(str.Length);
uint BufLen = Convert.ToUInt32(str.Length);


CryptEncrypt(hKey, IntPtr.Zero, 1, 0, null, out BufLen, 0);
int blen = Convert.ToInt32(BufLen);
//if the line is more than buffer it is cut off
if (str.Length >= blen)
{
str = str.Substring(0, Convert.ToInt32(BufLen));
}
byte[] Bstr = _encoding.GetBytes(str);
//if the line is less than buffer it is finished by its zero
if (Bstr.Length <= blen)
{
byte[] NewBstr = new byte[blen];
Bstr.CopyTo(NewBstr, 0);
Bstr = NewBstr;
}
CryptEncrypt(hKey, IntPtr.Zero, 1, 0, Bstr, out DataLen, BufLen);

//return BitConverter.ToString(Bstr);
//string st = Convert.ToBase64String(Bstr);

return ASCIIEncoding.ASCII.GetString(Bstr);
}



a Do javy jsem to přepsal tímto způsobem:


public static void encrypt2(String password, String plainText, String charset)
throws Exception
{
byte[] passwordData = password.getBytes(charset);
byte[] textData = plainText.getBytes(charset);

MessageDigest md = MessageDigest.getInstance("MD5");

md.reset();
byte[] md5HashPass = md.digest(passwordData);

SecretKeySpec rc2KeySpec = new SecretKeySpec(md5HashPass, "RC4");
Cipher rc4 = Cipher.getInstance("RC4");
rc4.init(Cipher.ENCRYPT_MODE, rc2KeySpec);

byte[] cipher = rc4.doFinal(textData);
String out = new String(cipher, charset);

// if (out.toUpperCase().startsWith("L"))
{
System.out.println("*encrypt2 **********************");

System.out.println(out);
}
}





Problém je v tom, že .NETí funkce vrací něco jiného než java. Pokud jsem si změnil providera ve funkci
CryptAcquireContext na "Microsoft Strong Cryptographic Provider", pak se vrací úplně stejný řetězec jako v javě. Ale potřeboval bych tam "Microsoft Base Cryptographic Provider v1.0",
tak jak je v původním kódu.

V šifrofání nejsem vůbec zběhlý. Prosím tedy o pomoc, co změnit ve funkci encrypt2, aby to vracelo stejná data jako GetHashPassword.
Je třeba instalovat na cílový stroj nějakého providera? Cílově by tato funkce měla jet na windows i androidu.

Děkuji předem za jakékoliv podněty

Citovat příspěvek

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: