Подтвердить что ты не робот

Interop Encryption/Decryption между Java/Net с AES и указанием IV и Key

Я пытаюсь реализовать симметричное шифрование с использованием AES, где я указываю ключ и IV. В рамках каждой экосистемы (Java → Java/.NET → .NET) шифрование и дешифрование работают так, как было разработано, но если я попытаюсь пройти между ними, я получаю множество ошибок в отношении заполнения и т.д. (Подробности ниже).

Я прочитал несколько сообщений, включая http://blogs.msdn.com/b/dotnetinterop/archive/2005/01/24/java-and-net-aes-crypto-interop.aspx, но ни один из них не имеет одного и того же варианта использования. Вот мой код:

JAVA

public class Main {

  public static void main(String[] args) throws Exception {
      String data = "Something to decrypt";

      String encrypt = Encrypt(data);
      System.out.println(encrypt);

      String decrypt = Decrypt(encrypt);
      System.out.println(decrypt);
  }

  private static String Encrypt(String raw) throws Exception {
      Cipher c = getCipher(Cipher.ENCRYPT_MODE);

      byte[] encryptedVal = c.doFinal(raw.getBytes("UTF-8"));
      return new BASE64Encoder().encode(encryptedVal);
  }

  private static Cipher getCipher(int mode) throws Exception {
      Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding", new SunJCE());

      //a random Init. Vector. just for testing
      byte[] iv = "e675f725e675f725".getBytes("UTF-8");

      c.init(mode, generateKey(), new IvParameterSpec(iv));
      return c;
  }

  private static String Decrypt(String encrypted) throws Exception {

      byte[] decodedValue = new BASE64Decoder().decodeBuffer(encrypted);

      Cipher c = getCipher(Cipher.DECRYPT_MODE);
      byte[] decValue = c.doFinal(decodedValue);

      return new String(decValue);
  }

  private static Key generateKey() throws Exception {
      SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
      char[] password = "[email protected]".toCharArray();
      byte[] salt = "[email protected]@1t".getBytes("UTF-8");

      KeySpec spec = new PBEKeySpec(password, salt, 65536, 128);
      SecretKey tmp = factory.generateSecret(spec);
      byte[] encoded = tmp.getEncoded();
      return new SecretKeySpec(encoded, "AES");

  }
}

.NET

internal class Program
{
private static void Main(string[] args)
{
    string encrypted = Encrypt("Something to decrypt");
    Console.Out.WriteLine(encrypted);

    string decrypted = Decrypt(encrypted);
    Console.Out.WriteLine(decrypted);

    Console.Out.WriteLine("Press any key to continue");
    Console.ReadKey();
}

private static string Encrypt(string raw)
{
    using (var csp = new AesCryptoServiceProvider())
    {
        ICryptoTransform e = GetCryptoTransform(csp, true);
        byte[] inputBuffer = Encoding.UTF8.GetBytes(raw);
        byte[] output = e.TransformFinalBlock(inputBuffer, 0, inputBuffer.Length);

        string encrypted = Convert.ToBase64String(output);

        return encrypted;
    }
}

public static string Decrypt(string encrypted)
{
    using (var csp = new AesCryptoServiceProvider())
    {
        var d = GetCryptoTransform(csp, false);
        byte[] output = Convert.FromBase64String(encrypted);
        byte[] decryptedOutput = d.TransformFinalBlock(output, 0, output.Length);

        string decypted = Encoding.UTF8.GetString(decryptedOutput);
        return decypted;
    }
}

private static ICryptoTransform GetCryptoTransform(AesCryptoServiceProvider csp, bool encrypting)
{
    csp.Mode = CipherMode.CBC;
    csp.Padding = PaddingMode.PKCS7;
    var passWord = "[email protected]";
    var salt = "[email protected]@lt";

    //a random Init. Vector. just for testing
    String iv = "e675f725e675f725";

    var spec = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(passWord), Encoding.UTF8.GetBytes(salt), 65536);
    byte[] key = spec.GetBytes(16);


    csp.IV = Encoding.UTF8.GetBytes(iv);
    csp.Key = key;
    if (encrypting)
    {
        return csp.CreateEncryptor();
    }
    return csp.CreateDecryptor();
}
}

Выходы для приложений:

JAVA

EO88Y8EjPAbaiZGoQM47z5i3vvy8jgVoehCPJDQES/4=

Something to decrypt

.NET

T/m/GatOCvFEJ4frVIoY8CbuQ1av97HoKdhUhAZcXp0=

Something to decrypt

Когда я пытаюсь расшифровать строку .NET в Java, я получаю: Исключение в потоке "main" javax.crypto.BadPaddingException: данный окончательный блок неправильно заполнен.

В .NET я получаю аналогичное: System.Security.Cryptography.CryptographicException не было обработано HResult = -2146233296 Message = Padding недопустимо и не может быть удалено.

В .NET я использую Rfc2898DeriveBytes для генерации моего ключа на основе пароля, соли и количества итераций. Я предполагаю, что это первопричина, поскольку в Java я использую SecretKeyFactory, надеясь достичь того же результата. Однако, если это причина, я не уверен, как примирить два...?

Спасибо за любую помощь.

** ОБНОВЛЕНО - РЕШЕНО **

Мальчик, я чувствую себя глупее, чем обычно. Проблема заключалась в опечатке в моем коде. Значение соли .NET имеет значение "1" и "L", где значение значения соли Java имеет значение "1" и "1" . Исправление этой ошибки устранило проблему. Извините, что трачу любое время.

.NET

var salt = "[email protected]@lt";

Java

byte[] salt = "[email protected]@1t"
4b9b3361