C # / Java | AES256 chiffrer / déchiffrer

Je souhaite chiffrer toutes les données que j’envoie via les sockets Java / C # (serveur Java, client C #). J’aimerais utiliser AES256, mais je ne parviens pas à obtenir les codes Java et C # pour générer le même code crypté. Quelqu’un peut-il me donner deux exemples, l’un en Java et l’autre en C #, qui génèrent les mêmes résultats et les déchiffrent correctement?

Ce que j’ai essayé jusqu’à présent:

public Encrypt(AOBCore instance){ try { Ssortingng message="This is just an example"; // Get the KeyGenerator KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(256); // 192 and 256 bits may not be available // Generate the secret key specs. SecretKey skey = kgen.generateKey(); //Cantget 'test' in here... byte[] raw = skey.getEncoded(); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); // Instantiate the cipher Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(message.getBytes()); System.out.println("encrypted ssortingng: " + asHex(encrypted)); cipher.init(Cipher.DECRYPT_MODE, skeySpec); byte[] original = cipher.doFinal(encrypted); Ssortingng originalSsortingng = new Ssortingng(original); System.out.println("Original ssortingng: " + originalSsortingng + " " + asHex(original)); } catch (Exception e) { instance.logMessage(e.getMessage()); } } public static Ssortingng asHex (byte buf[]) { SsortingngBuffer strbuf = new SsortingngBuffer(buf.length * 2); int i; for (i = 0; i < buf.length; i++) { if (((int) buf[i] & 0xff) < 0x10) strbuf.append("0"); strbuf.append(Long.toString((int) buf[i] & 0xff, 16)); } return strbuf.toString(); } 

}

 static void Main(ssortingng[] args) { while (true) { var plain = Console.ReadLine(); var key = GenerateKey(256); var encoded = Encrypt(plain, key, 256); Console.WriteLine("Encoded: " + encoded); Console.WriteLine(Decrypt(encoded, key, 256)); } } private static ssortingng GenerateKey(int keySize) { return "test"; } private static ssortingng Encrypt(ssortingng plainStr, ssortingng completeEncodedKey, int keySize) { RijndaelManaged aesEncryption = new RijndaelManaged(); aesEncryption.KeySize = keySize; aesEncryption.BlockSize = 256; aesEncryption.Mode = CipherMode.CBC; aesEncryption.Padding = PaddingMode.PKCS7; aesEncryption.IV = Convert.FromBase64Ssortingng(ASCIIEncoding.UTF8.GetSsortingng(Convert.FromBase64Ssortingng(completeEncodedKey)).Split(',')[0]); aesEncryption.Key = Convert.FromBase64Ssortingng(ASCIIEncoding.UTF8.GetSsortingng(Convert.FromBase64Ssortingng(completeEncodedKey)).Split(',')[1]); byte[] plainText = ASCIIEncoding.UTF8.GetBytes(plainStr); ICryptoTransform crypto = aesEncryption.CreateEncryptor(); // The result of the encryption and decryption byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length); return Convert.ToBase64Ssortingng(cipherText); } private static ssortingng Decrypt(ssortingng encryptedText, ssortingng completeEncodedKey, int keySize) { RijndaelManaged aesEncryption = new RijndaelManaged(); aesEncryption.KeySize = keySize; aesEncryption.BlockSize = 128; aesEncryption.Mode = CipherMode.CBC; aesEncryption.Padding = PaddingMode.PKCS7; aesEncryption.IV = Convert.FromBase64Ssortingng(ASCIIEncoding.UTF8.GetSsortingng(Convert.FromBase64Ssortingng(completeEncodedKey)).Split(',')[0]); aesEncryption.Key = Convert.FromBase64Ssortingng(ASCIIEncoding.UTF8.GetSsortingng(Convert.FromBase64Ssortingng(completeEncodedKey)).Split(',')[1]); ICryptoTransform decrypto = aesEncryption.CreateDecryptor(); byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length); return ASCIIEncoding.UTF8.GetSsortingng(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length)); } 

Le problème est que vous ne spécifiez pas le mode de chiffrement ou le remplissage dans le code Java. Cela utilisera les valeurs par défaut de l’algorithme, ce que vous ne devez jamais faire lorsque l’interopérabilité avec d’autres bibliothèques est requirejse. Initialisez votre Cipher comme ceci:

 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

Selon cette réponse, PKCS5 en Java devrait être compatible avec PKCS7 en .Net. Puisque vous utilisez sagement CBC, vous allez avoir besoin de modifier le code pour utiliser le même vecteur d’initialisation pour le cryptage et le décryptage. Vous ne devez PAS utiliser la clé secrète pour cela. L’IV doit être généré de manière aléatoire. Vous pouvez utiliser le cipher.getIV() généré par Java Cipher pour le chiffrement en appelant cipher.getIV() .

Veillez également à être cohérent avec les codages de caractères indiqués dans les commentaires.