tags:

views:

462

answers:

3

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# produces: ff53bc51c0caf5de53ba850f7ba08b58345a89a51356d0e030ce1367606c5f08
java produces: 375c52fd202696dba679e57f612ee95e707ccb05aff368b62b2802d5fb685403

Can somebody help me to fix my code?

A: 

I think the algorithm is built in slighty different way and/or the salt key is interpered in different way.

Kristoffer
A: 

In the Java code, you do not use the IV.

I am not savvy enough in C# to help you directly, but I can give some information.

Rijndael, aka "the AES", encrypts blocks of 16 bytes. To encrypt a long message (e.g. your test message, when encoding, is 20 bytes long), Rijndael must be invoked several times, with some way to chain the invocations together (also, there is some "padding" to make sure that the input length is a multiple of 16). The CBC mode performs such chaining.

In CBC, each block of data is combined (bitwise XOR) with the previous encrypted block prior to being itself encrypted. Since the first block of data has no previous block, we add a new conventional "zero-th block" called the IV. The IV should be chosen as 16 random bytes. The decrypting party will need the IV. The IV needs not be secret (that's the difference between the IV and the key) so it is often transmitted along the message.

In your Java code, you do not specify the IV, you just create a variable called iv and do not use it. So the Rijndael implementation is on its own for that. Chances are that it generated a random IV. Similarly, you do not give an IV to the Rijndael implementation in the C# code. So it is quite plausible that there again a random IV was selected. But not the same than the one in the Java code, hence the distinct results.

(Note: you 20-byte input string is padded to 32 bytes. You give two "results" in hexadecimal, of length 32 bytes each. This is coherent but means that those results do not include the IV -- otherwise they would be 48-byte long.)

Thomas Pornin
A: 

In the Java code, you do not use the IV. I use lcrypto-j2me-145 from www.bouncycastle.org/ and no IV in RijndaelEngine! how to set it?

Kumar Gashish