IV problems Java -> C#

I have a problem encrypting data in Java to match C# results. Its a RC2 encryption using CBC mode. my problem comes with the IV parameter, cause they (C#) use a 16 byte IV. Ive tried to apply it to my Java code with no luck, using RC2ParameterSpec which only takes the first 8 bytes so the results dont match, and the IvParameterSpec but get an exception when called upon saying it must be 8 bytes long. All documentation ive seen points to 8 byte IVs, so my question is Is it possible to make it work with a 16 byte IV?, if so, how?

[540 byte] By [krima] at [2007-10-2 20:14:53]
# 1

RC2ParameterSpec has a constructor that allows you to specify which

bytes to use for the IV. Have you tried this?

(its the 3rd constructor, link isnt posting right)

http://java.sun.com/j2se/1.4.2/docs/api/javax/crypto/spec/RC2ParameterSpec.html#RC2ParameterSpec(int,%20byte[],%20int)

You'd still have to make sure that you're using the same IV as the C# side.

cdelikata at 2007-7-13 22:57:06 > top of Java-index,Security,Cryptography...
# 2
I am using the same IV as the one in the C# code.I also have tried the RC2ParameterSpec giving the offset, but get the same problem since it only takes 8 bytes from the IV, just starts from the given offset instead of the beggining of the IV and takes the next 7 bytes.
krima at 2007-7-13 22:57:06 > top of Java-index,Security,Cryptography...
# 3
ouch, you're right.sorry about that.I replied too fast...I guess the next question is: have you looked at the Bouncy Castle?I'll admit I havent done anything with RC2, but BC tends to have a lot more options than the JCE.
cdelikata at 2007-7-13 22:57:06 > top of Java-index,Security,Cryptography...
# 4
RC2 is an 8-byte block cipher, so a 16 byte IV doesn't make any sense. I don't think the C# routines are really using a 16 byte IV.
ghstarka at 2007-7-13 22:57:06 > top of Java-index,Security,Cryptography...
# 5

well maybe this will help

here is the C# code :

Private bytIV() As Byte = {123, 231, 20, 6, 70, 45, 24, 67, 8, 65, 32, 45, 154, 222, 144, 43}

Private Const sKey = "Key"

Public Function EncryptText(ByVal sValue As String) As String

Dim bytValue() As Byte

Dim bytKey() As Byte

Dim bytEncoded() As Byte

Dim iLen As Integer, iRemaining As Integer

Dim objMS As New MemoryStream()

Dim objCrypt As CryptoStream

Dim objRM As RC2CryptoServiceProvider

Try

bytValue = Encoding.UTF8.GetBytes(sValue.ToCharArray)

iLen = Len(sKey)

bytKey = Encoding.ASCII.GetBytes(sKey.ToCharArray)

objRM = New RC2CryptoServiceProvider()

objCrypt = New CryptoStream(objMS, objRM.CreateEncryptor(bytKey, bytIV), CryptoStreamMode.Write)

objCrypt.Write(bytValue, 0, bytValue.Length)

objCrypt.FlushFinalBlock()

bytEncoded = objMS.ToArray

objMS.Close()

objCrypt.Close()

Return Convert.ToBase64String(bytEncoded)

Catch err As System.Exception

Throw New Exception("error " & System.Reflection.MethodInfo.GetCurrentMethod.Name & " function:" & err.Message)

Finally

If Not objMS Is Nothing Then objMS.Close()

If Not objCrypt Is Nothing Then objCrypt.Close()

objRM = Nothing

objMS = Nothing

objCrypt = Nothing

End Try

and here is my adaptation in Java

public class RC2 {

public static String execute(String data) {

String instr = data;

String rutenc;

String key = "Key";

byte[] encriptado;

byte[] aEncriptar;

byte[] mikey = key.getBytes();

byte[] iv = {(byte) 123, (byte) 231, (byte) 20, (byte) 6, (byte) 70, (byte) 45, (byte) 24, (byte) 67, (byte) 8, (byte) 65, (byte) 32, (byte) 45, (byte) 154, (byte) 222, (byte) 144, (byte) 43};

try {

SecretKeySpec key = new SecretKeySpec(mikey, "RC2");

RC2ParameterSpec rc2Spec = new RC2ParameterSpec(128, iv);

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

cipher.init(Cipher.ENCRYPT_MODE, key, rc2Spec);

aEncriptar = instr.getBytes("UTF8");

encriptado = cipher.doFinal(aEncriptar);

rutenc = new BASE64Encoder().encodeBuffer(encriptado);

return(rutenc);

} catch (Exception e) {

System.out.println("Error : " + e);

return(null);

}

}

}

krima at 2007-7-13 22:57:06 > top of Java-index,Security,Cryptography...
# 6

krim-

That is not C#, its VB.NET. But the libraries are all the same, so its just a

matter of syntax. I dont have a VB.NET compiler or the time to translate

your code right now, but I did throw a couple lines together in C# that

attempts to set a 16-byte IV for RC2. It throws an error.

Unhandled Exception: System.Security.Cryptography.CryptographicException: Specified initialization vector (IV) does not match the block size for this algorithm.

at System.Security.Cryptography.SymmetricAlgorithm.set_IV(Byte[] value)

at RC2_IV.MyMainClass.Main()

Also, checking the length of the IV byte array returns 8.

using System;

using System.IO;

using System.Text;

using System.Security.Cryptography;

namespace RC2_IV {

class MyMainClass {

public static void Main() {

RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();

Console.WriteLine("IV is {0} bytes", rc2.IV.Length);

byte[] iv =

{123, 231, 20, 6, 70, 45, 24, 67,

8, 65, 32, 45, 154, 222, 144, 43};

rc2.IV = iv;

Console.WriteLine("IV = {0}", BitConverter.ToString(rc2.IV));

}

}

}

I dont think the VB side is doing what you think it is. Can you modify to only

use an 8-byte IV. Or try your java code only using the first 8 bytes of the

IV. Maybe the VB side's RC2 Provider class is just taking the first 8 bytes of the array...

cdelikata at 2007-7-13 22:57:06 > top of Java-index,Security,Cryptography...
# 7

Thanks for the help cdelikat, you where right, ive managed to recreate the VB.net class and run some tests, it was taking the first 8 bytes of the array. Then i just replaced RC2ParameterSpec rc2Spec = new RC2ParameterSpec(128, iv) for IvParameterSpec ivSpec = new IvParameterSpec(iv,0,8) in my java code and it worked like a charm.

krima at 2007-7-13 22:57:06 > top of Java-index,Security,Cryptography...