Přepis šifrování z .NETu do javy – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Přepis šifrování z .NETu do javy – Java – Fórum – Programujte.comPřepis šifrování z .NETu do javy – Java – Fórum – Programujte.com

 

Kleo
~ Anonymní uživatel
3 příspěvky
11. 3. 2015   #1
-
0
-

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

Nahlásit jako SPAM
IP: 46.227.12.–
q
~ Anonymní uživatel
219 příspěvků
12. 3. 2015   #2
-
0
-

Jestli jsem všechno správně pochopil, tak v MS Base je ten klíč 40-bitový a mohlo by stačit ten hash oříznout:

SecretKeySpec rc2KeySpec = new SecretKeySpec(md5HashPass, 0, 5, "RC4");
Nahlásit jako SPAM
IP: 213.211.51.–
Kleo
~ Anonymní uživatel
3 příspěvky
14. 3. 2015   #3
-
0
-

#2 q
Výsledek je pořád stejný (špatný). 

Funkcím předávám:
string password = "aaaa";
string text = "12345678"; 

V javě dostanu zpět:

z ořezáním:
120, -121, 72, 57, -82, 59, 104, 30 -> new String(cipher, "ASCII") =  x�H9�;h 

bez ořezání:
93, 70, -57, -121, -64, -29, -80, 3  -> new String(cipher, "ASCII") =  ]F�����

V .NETu

"Microsoft Base Cryptographic Provider v1.0"
30 ,165, 38 ,107,11, 45, 132 ,77 -> ASCII = ?&k -?M

Pokud však změním providera na "Microsoft Strong Cryptographic Provider", dostanu zpět:
93,70 ,199,135 ,192,227,176, 3 - > ]F????? 

já bych však potřeboval, aby výsledek byl v javě stejný jako s Base providerem....

Díky

Nahlásit jako SPAM
IP: 31.31.228.–
ingiraxo+15
Grafoman
14. 3. 2015   #4
-
0
-

pozor na to, že alg. v .net a v javě nemusí být stejný! rozhodně bych se na to nespolíhal

zkus na obou stranách použít utf8 kódování, případně AES nebo DES nebo přes certifikát, kterej přiložít do obou app (třeba do resource)

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
q
~ Anonymní uživatel
219 příspěvků
16. 3. 2015   #5
-
0
-

#3 Kleo
Tak nechat 128, ale ty nad 40 vynulovat.

byte[] key = Arrays.copyOf(Arrays.copyOfRange(md5HashPass, 0, 5), 16);
SecretKeySpec rc2KeySpec = new SecretKeySpec(key, "RC4");
Nahlásit jako SPAM
IP: 213.211.51.–
Kleo
~ Anonymní uživatel
3 příspěvky
30. 3. 2015   #6
-
0
-

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

Nahlásit jako SPAM
IP: 46.227.12.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 3 hosté

Podobná vlákna

Použití Javy? — založil vesík

Použitelnost Javy? — založil Algon Janer

Přepsání C do Javy — založil Neony

Cvičení z Javy — založil Michal

Projekt z Javy — založil neo225

Moderátoři diskuze

 

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