AES-Verschlüsselung in Java-und Entschlüsselung in C#
Hallo, ich habe Verschlüsselte Hex-string und Key verschlüsselt mit AES-Algorithmus.
Code:
final String key = "=abcd!#Axd*G!pxP";
final javax.crypto.spec.SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
final javax.crypto.Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte [] encryptedValue = cipher.doFinal(input.getBytes());
return new String(org.apache.commons.codec.binary.Hex.encodeHex(encryptedValue));
Nun ich versuche es zu entschlüsseln mit C#
Code:
RijndaelManaged rijndaelCipher = new RijndaelManaged();
//Assumed Mode and padding values.
rijndaelCipher.Mode = CipherMode.ECB;
rijndaelCipher.Padding = PaddingMode.None;
//AssumedKeySize and BlockSize values.
rijndaelCipher.KeySize = 0x80;
rijndaelCipher.BlockSize = 0x80;
//Convert Hex keys to byte Array.
byte[] encryptedData = hexStringToByteArray(textToDecrypt);
byte[] pwdBytes = Encoding.Unicode.GetBytes(key);
byte[] keyBytes = new byte[0x10];
int len = pwdBytes.Length;
if (len > keyBytes.Length)
{
len = keyBytes.Length;
}
Array.Copy(pwdBytes, keyBytes, len);
rijndaelCipher.Key = keyBytes;
rijndaelCipher.IV = keyBytes;
//Decrypt data
byte[] plainText = rijndaelCipher.CreateDecryptor().TransformFinalBlock(encryptedData, 0, encryptedData.Length);
str = Encoding.UTF8.GetString(plainText);
und
static private byte[] HexToBytes(string str)
{
if (str.Length == 0 || str.Length % 2 != 0)
return new byte[0];
byte[] buffer = new byte[str.Length / 2];
char c;
for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
{
//Convert first half of byte
c = str[sx];
buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0')) << 4);
//Convert second half of byte
c = str[++sx];
buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0'));
}
return buffer;
}
aber die Ausgabe ist nicht wie erwartet.
Bitte darauf hinweisen wo ich bin mache ich falsch?
InformationsquelleAutor Test | 2011-03-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dein code hat ein großes problem: Es ist eine Vermischung der Zeichensätze!
In Java, die Sie anrufen
key.getBytes()
ohne Argumente. Diese Methode gibt die UTF-8 und CP1252/ISO 8859-1 kodierten Daten abhängig von Ihrem Betriebssystem und die Standard-Zeichenkodierung in Java.Auf C# - Seite die Sie verwenden
Encoding.Unicode.GetBytes(key)
- "Unicode".Net ist ein synonym für double-byte-Zeichen alias UTF-16 (Little-Endian). Deshalb sind Sie mit einem anderen Schlüssel in C#.Sollten Sie in der Lage, um zu sehen, den Unterschied durch Vergleich der Anzahl von bytes in Java und C#:
Java:
"=abcd!#Axd*G!pxP".getBytes().length = 16
C#:
Encoding.Unicode.GetBytes("=abcd!#Axd*G!pxP").Length = 32
Empfehle ich Sie verwenden byte-arrays anstelle von Strings zum definieren einen kryptographischen Schlüssel.
Update: ein Weiterer Unterschied ist, dass Sie einen Initialisierungsvektor (IV) in C#, die man nicht in Java. Wie Sie mit Hilfe der EZB die IV sollte nicht verwendet werden, aber wenn Sie ändern, um die CBC-zum Beispiel dies macht einen großen Unterschied.
Haben Sie Ihre Java-code zu
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
wie Chris Thompson vorgeschlagen?EZB sollte nur verwendet werden für die Verschlüsselung von Schlüsseln und anderen Daten angesehen werden kann, zufällig, bitte raten, zu verwenden CBC und einen anderen IV für jedes Stück von Daten mit dem gleichen Schlüssel verschlüsselt. Es ist wohl eher nützlich, um anzugeben, PKCS#5-padding; ohne Polsterung bedeutet, dass die Länge der kodierten Daten müssen implizit bekannt.
InformationsquelleAutor Robert
Brauchte ich etwas, das nicht nur für C# sondern auch Silverlight und Windows Phone 7 kompatibel ist. Und ich bin definitiv krank, die fehlende vollständige Beispiele etwas akzeptabel, sowohl in Java und C# (und Base64-basiert).
Code ist nichts besonderes, aber funktioniert. Bitte fühlen Sie sich frei, verbessert Sie, als ich markierte diese als " community-wiki, aber stellen Sie sicher, um es zu testen, bevor Sie änderungen an Ihr vornehmen.
Hier der C# code:
Hier ist die Android-kompatible Java-code:
Zur Base64-Konvertierung finden Sie die hervorragende Umsetzung auf http://iharder.net/base64.
Ich hoffe das spart Menschen Stunden.
seed
für Passwort 2) wird das Kennwort als IV. Tun Sie das nicht. Sie brauchen eine neue random-IV-pro-Verschlüsselung. 3) Es verwendet ein Kennwort direkt als Schlüssel, ohne entsprechende KDF 4) Es fehlt Authentifizierung => anfällig für padding-OrakelVielen Dank für das tolle feedback. Ich bin kein Krypto-Experte. Sie sind das meiste willkommen, zum Bearbeiten der Antwort und den code aktualisieren, passen die standards guter crypto - ich bin mir sicher, dass würde der Gemeinschaft helfen, eine Menge.
Wie genau hast du benutzt/Aufruf der
Encrypt<TSymmetricAlgorithm>(string input).....
Methode in C#. Ich habe versucht, mitDecrypt5<TSymmetricAlgorithm>("myEncryptedStringxyzabcblahblah");
aber gab es mir einen Fehler. Zu sagen, dass ich nicht verwenden können, eine abstrakte Klasse. Bezeichne ich es falsch? Was ist eine nicht-abstrakte Klasse, die ich nutzen kann? Danke.muss vom Typ
SymmetricAlgorithm
und eine konkrete Umsetzung. Hier ist die Dokumentation Seite: msdn.microsoft.com/en-us/library/... Hier sind die konkreten Typen, die es umzusetzen: System.Sicherheit.Die Kryptographie.Aes-System.Sicherheit.Die Kryptographie.DES, Systems.Sicherheit.Die Kryptographie.RC2-System.Sicherheit.Die Kryptographie.Rijndael, System.Sicherheit.Die Kryptographie.TripleDES. So ein Beispiel nennen würde, wieEncrypt<System.Security.Cryptography.TripleDES>('your input')
.InformationsquelleAutor
Versuchen Sie, diese Kombination:
InformationsquelleAutor Alf
Ich vermute das der Fehler ist, dass Sie nicht die Angabe einer Polsterung oder Betriebsart, in der Java Seite dieser Gleichung. Ich bin mir nicht sicher, was Java AES-Implementierung standardmäßig, aber ich würde anfangen, indem Sie angeben, wenn Sie erhalten die Chiffre. Zum Beispiel:
Benötigen Sie zum nachschlagen der Polsterung unterstützt Schemata und Modi für AES in Java und dann stellen Sie sicher, konfigurieren Sie Ihr C# - code zu verwenden, der genau die gleiche Konfiguration.
InformationsquelleAutor Chris Thompson