Anonymní profil Kleo – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Anonymní profil Kleo – Programujte.comAnonymní profil Kleo – Programujte.com

 

Příspěvky odeslané z IP adresy 46.227.12.–

Kleo
Java › Přepis šifrování z .NETu do…
30. 3. 2015   #200871

#5 q
Díky moc. To je přesně ono.....

Kleo
Java › Přepis šifrování z .NETu do…
11. 3. 2015   #200156

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

 

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý