C # / Java | AES256 шифрование / дешифрование - PullRequest
1 голос
/ 06 марта 2012

Я хочу зашифровать все данные, которые я отправляю через сокеты Java / C # (сервер Java, клиент C #). Я хотел бы использовать AES256, но я не могу заставить Java и C # генерировать один и тот же зашифрованный код. Кто-нибудь может дать мне два примера: 1 на Java и 1 на C #, которые генерируют одинаковые результаты и правильно дешифруют результаты?

Что я пробовал до сих пор:

public Encrypt(AOBCore instance){
    try {
        String 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 string: " + asHex(encrypted));

           cipher.init(Cipher.DECRYPT_MODE, skeySpec);
           byte[] original =
             cipher.doFinal(encrypted);
           String originalString = new String(original);
           System.out.println("Original string: " +
             originalString + " " + asHex(original));
    } catch (Exception e) {
        instance.logMessage(e.getMessage());
    }
}

public static String asHex (byte buf[]) {
      StringBuffer strbuf = new StringBuffer(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(string[] 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 string GenerateKey(int keySize)
    {
        return "test";
    }

    private static string Encrypt(string plainStr, string completeEncodedKey, int keySize)
    {
        RijndaelManaged aesEncryption = new RijndaelManaged();
        aesEncryption.KeySize = keySize;
        aesEncryption.BlockSize = 256;
        aesEncryption.Mode = CipherMode.CBC;
        aesEncryption.Padding = PaddingMode.PKCS7;
        aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);
        aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(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.ToBase64String(cipherText);
    }

    private static string Decrypt(string encryptedText, string completeEncodedKey, int keySize)
    {
        RijndaelManaged aesEncryption = new RijndaelManaged();
        aesEncryption.KeySize = keySize;
        aesEncryption.BlockSize = 128;
        aesEncryption.Mode = CipherMode.CBC;
        aesEncryption.Padding = PaddingMode.PKCS7;
        aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);
        aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]);
        ICryptoTransform decrypto = aesEncryption.CreateDecryptor();
        byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length);
        return ASCIIEncoding.UTF8.GetString(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length));
    }

1 Ответ

4 голосов
/ 06 марта 2012

Проблема в том, что вы не указываете шифровальный режим или заполнение в коде Java. При этом будет использоваться алгоритм по умолчанию, что никогда не требуется, если требуется взаимодействие с другими библиотеками. Инициализируйте ваш Cipher следующим образом:

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

PKCS5 в Java должен быть совместим с PKCS7 в .Net в соответствии с этим ответом. Поскольку вы разумно используете CBC, вам нужно будет изменить код, чтобы использовать один и тот же вектор инициализации для шифрования и дешифрования. Вы должны НЕ использовать секретный ключ для этого. IV должен генерироваться случайным образом. Вы можете использовать IV, сгенерированный Java Cipher для шифрования, вызвав cipher.getIV().

Кроме того, соблюдайте кодировку символов, как уже упоминалось в комментариях.

...