Как сделать это: J2ME шифрует C # расшифровывает И J2ME расшифровывает C # шифрует? - PullRequest
1 голос
/ 29 января 2010

C #

string              keystr         = "0123456789abcdef0123456789abcdef";
string              plainText   = "www.bouncycastle.org";
  RijndaelManaged crypto = new RijndaelManaged();

  crypto.KeySize = 128;
  crypto.Mode = CipherMode.CBC;
  crypto.Padding = PaddingMode.PKCS7;
  crypto.Key = keystr.ToCharArray().Select(c=>(byte)c).ToArray();
  // get the IV and key for writing to a file
  byte[] iv = crypto.IV;
  byte[] key = crypto.Key;


  // turn the message into bytes
  // use UTF8 encoding to ensure that Java can read in the file properly
  byte[] plainBytes = Encoding.UTF8.GetBytes(plainText.ToCharArray());

  // Encrypt the Text Message using AES (Rijndael) (Symmetric algorithm)
  ICryptoTransform sse = crypto.CreateEncryptor();
  MemoryStream encryptedFs = new MemoryStream();
  CryptoStream cs = new CryptoStream(encryptedFs, sse, CryptoStreamMode.Write);
  try
  {
    cs.Write(plainBytes, 0, plainBytes.Length);
    cs.FlushFinalBlock();
    encryptedFs.Position = 0;

    string result = string.Empty;
    for (int i = 0; i < encryptedFs.Length; i++)
    {
      int read = encryptedFs.ReadByte();
      result += read.ToString("x2");  
    }

  }
  catch (Exception e)
  {
    Console.WriteLine(e.Message);

  }
  finally
  {
    encryptedFs.Close();
    cs.Close();

  }
}

Java:

private String              key         = "0123456789abcdef0123456789abcdef";
private String              plainText   = "www.bouncycastle.org";

cipherText = performEncrypt(Hex.decode(key.getBytes()), plainText);

private byte[] performEncrypt(byte[] key, String plainText)
{
    byte[] ptBytes = plainText.getBytes();
    final RijndaelEngine rijndaelEngine = new RijndaelEngine();


    cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(rijndaelEngine));

    String name = cipher.getUnderlyingCipher().getAlgorithmName();
    message("Using " + name);
    byte[]iv = new byte[16];
    final KeyParameter keyParameter = new KeyParameter(key);

    cipher.init(true, keyParameter);



    byte[] rv = new byte[cipher.getOutputSize(ptBytes.length)];

    int oLen = cipher.processBytes(ptBytes, 0, ptBytes.length, rv, 0);
    try
    {
        cipher.doFinal(rv, oLen);
    }
    catch (CryptoException ce)
    {
        message("Ooops, encrypt exception");
        status(ce.toString());
    }
    return rv;
}

C # производит: ff53bc51c0caf5de53ba850f7ba08b58345a89a51356d0e030ce1367606c5f08
Java производит: 375c52fd202696dba679e57f612ee95e707ccb05aff368b62b2802d5fb685403

Может кто-нибудь помочь мне исправить мой код?

Ответы [ 2 ]

1 голос
/ 29 января 2010

В коде Java вы не используете IV.

Я недостаточно разбираюсь в C #, чтобы помочь вам напрямую, но могу дать некоторую информацию.

Rijndael, он же "AES", шифрует блоки по 16 байт. Чтобы зашифровать длинное сообщение (например, ваше тестовое сообщение при кодировании имеет длину 20 байт), Rijndael должен быть вызван несколько раз, с некоторым способом объединить вызовы вместе (также, есть некоторая «заполненность», чтобы убедиться, что длина кратна 16). Режим CBC выполняет такую ​​цепочку.

В CBC каждый блок данных объединяется (поразрядно XOR) с предыдущим зашифрованным блоком до того, как сам будет зашифрован. Поскольку первый блок данных не имеет предыдущего блока, мы добавляем новый условный «нулевой блок», называемый IV. IV должен быть выбран как 16 случайных байтов. Расшифровывающей стороне понадобится IV. IV не должен быть секретным (в этом разница между IV и ключом), поэтому он часто передается вместе с сообщением.

В вашем Java-коде вы не указываете IV, вы просто создаете переменную с именем iv и не используете ее. Так что реализация Rijndael сама по себе для этого. Скорее всего, это породило случайный IV. Точно так же вы не даете IV для реализации Rijndael в коде C #. Так что вполне вероятно, что снова был выбран случайный IV. Но не такой, как в коде Java, отсюда и отличные результаты.

(Примечание: ваша 20-байтовая строка ввода дополняется до 32 байтов. Вы даете два «результата» в шестнадцатеричном формате длиной 32 байта каждый. Это согласованно, но означает, что эти результаты не включают IV - иначе они будет длиной 48 байт.)

0 голосов
/ 29 января 2010

Я думаю, что алгоритм построен немного по-другому, и / или солт-ключ интерпретируется по-другому.

...