PDA

View Full Version : [C#] Decriptare una stringa - Rijndael


SnakeX
16-05-2012, 00:22
Salve a tutti,

sto cercando di decriptare una stringa criptata con Rijndael, che prevede un padding sia della chiave, sia dell'IV, aggiungendo dei cancelletti alla destra della stringa se la lunghezza è inferiore a 16.
La stringa da decriptare proviene da un webservice che me la manda in formato XML, insieme con la key, mentre l'IV è il Mac-Address del pc richiedente. Mi sono stati forniti entrambi gli algoritmi dai proprietari del webservice, sia di encrypt che di decrypt, ma quando provo ad eseguire la funzione di decrypt su una stringa inviatami dal webservice, il mio programmino in c# si incaglia (o meglio, non raggiunge il risultato), mostrandomi l'errore "Il riempimento non è valido e non può essere rimosso", all'istruzione:

while ((num5 = stream3.ReadByte()) != -1)

Sotto riporto il codice di entrambe le funzioni.


public static string Decrypt(string strInputString, string strKeyString, string myIV)
{
if ((strInputString == null) || (strInputString.Length == 0))
{
return strInputString;
}
try
{
int num5;
int keySize = 0x100;
int blockSize = 0x100;
int length = keySize / 0x10;
if (strKeyString.Length > length)
{
strKeyString = strKeyString.Substring(0, length);
}
if (strKeyString.Length < length)
{
strKeyString = strKeyString.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(strKeyString);
if (myIV.Length > length)
{
myIV = myIV.Substring(0, length);
}
if (myIV.Length < length)
{
myIV = myIV.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(myIV);
byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
RijndaelManaged managed = new RijndaelManaged {
BlockSize = blockSize,
KeySize = keySize
};
MemoryStream stream = new MemoryStream();
for (int i = 0; i < strInputString.Length; i += 2)
{
stream.WriteByte(byte.Parse(strInputString.Substring(i, 2), NumberStyles.AllowHexSpecifier));
}
stream.Position = 0L;
MemoryStream stream2 = new MemoryStream();
CryptoStream stream3 = new CryptoStream(stream, managed.CreateDecryptor(bytes, rgbIV), CryptoStreamMode.Read);
while ((num5 = stream3.ReadByte()) != -1)
{
stream2.WriteByte((byte) num5);
}
stream3.Close();
stream2.Close();
stream.Close();
byte[] buffer3 = stream2.ToArray();
return Encoding.Unicode.GetString(buffer3);
}
catch (Exception exception)
{
Log.Error(exception.Message);
}
}

public static string Encrypt(string strInputString, string strKeyString, string myIV)
{
if ((strInputString == null) || (strInputString.Length == 0))
{
return strInputString;
}
try
{
int num4;
int keySize = 0x100;
int blockSize = 0x100;
int length = keySize / 0x10;
if (strKeyString.Length > length)
{
strKeyString = strKeyString.Substring(0, length);
}
if (strKeyString.Length < length)
{
strKeyString = strKeyString.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(strKeyString);
if (myIV.Length > length)
{
myIV = myIV.Substring(0, length);
}
if (myIV.Length < length)
{
myIV = myIV.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(myIV);
byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
string str = "";
RijndaelManaged managed = new RijndaelManaged {
BlockSize = blockSize,
KeySize = keySize
};
MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(strInputString));
MemoryStream stream2 = new MemoryStream();
CryptoStream stream3 = new CryptoStream(stream2, managed.CreateEncryptor(bytes, rgbIV), CryptoStreamMode.Write);
while ((num4 = stream.ReadByte()) != -1)
{
stream3.WriteByte((byte) num4);
}
stream3.Close();
stream2.Close();
stream.Close();
foreach (byte num5 in stream2.ToArray())
{
str = str + num5.ToString("X2");
}
return str;
}
catch (Exception exception)
{
Log.Error(exception.Message);
}
}
}


Non riesco proprio a venirne a capo. Nella documentazione MSDN c'è scritto che questo errore si verifica quando l'IV usato per il decrypt è diverso dall'IV utilizzato per l'encrypt, il problema è che l'IV è il MAC Address che io stesso ricavo ed invio con una funzione GetMacAddress(). Qualcuno sa darmi lumi ? :help:

lorenzo001
16-05-2012, 08:36
Sei sicuro che il MAC che usi sia nello stesso formato di quello usato prima?

Ad esempio, tutto in maiuscolo o tutto in minuscolo (per la parte delle lettere a-f) ?

SnakeX
16-05-2012, 13:40
Ciao lorenzo, grazie della risposta.


Sei sicuro che il MAC che usi sia nello stesso formato di quello usato prima?


Si. Il MAC viene ricavato da una funzione nativa C# del modulo Network. Il server che mi manda la stringa criptata, per criptarla, utilizza come IV il MAC che io gli mando, così come lo ricavo io dalla funzione (la Key la conosce già).


Ad esempio, tutto in maiuscolo o tutto in minuscolo (per la parte delle lettere a-f) ?

Tutto maiuscolo, infatti nella funzione che ricava il MAC c'è un bel ToUpper(). So che in alcune notazioni il MAC viene rappresentato con i : come separatore e non col trattino, ma ho provato a forzarlo in entrambi i modi, l'errore rimane.