0

I am trying to write the Java equivalent of some .NET encryption code so that they can decrypt our information over a webservice.

Here is the .NET method:

public static string AESEncrypt(string text, string keyPhrase)
    {
        byte[] salt = { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 };
        byte[] data = Encoding.Unicode.GetBytes(text);
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(keyPhrase, salt);

        Rijndael algorithm = Rijndael.Create();
        algorithm.Key = pdb.GetBytes(32);
        algorithm.IV = pdb.GetBytes(16);

        MemoryStream mStream = new MemoryStream();
        CryptoStream cStream = new CryptoStream(mStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write);
        cStream.Write(data, 0, data.Length);
        cStream.Close();
        byte[] bytes = mStream.ToArray();

        return Convert.ToBase64String(bytes);
    }

Here is my failing attempt at a Java version:

public static String encrypt(String text, String keyPhrase) throws Exception {
        byte[] salt = { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 };
        byte[] data = text.getBytes("UTF-16LE");
        PBEKeySpec spec = new PBEKeySpec(keyPhrase.toCharArray(), salt, 1);

        SecretKey secret = new SecretKeySpec(keyPhrase.getBytes("UTF-16LE"), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        cipher.init(Cipher.ENCRYPT_MODE, secret);
        byte[] ciphertext = cipher.doFinal(data);
        return Base64.encodeBase64String(ciphertext);
    }

The first problem I have is figuring out how to match the PasswordDeriveBytes thing for the key and the iv, although I am sure the rest is wrong, but baby steps. Does anyone know how to match the output in the Java version?

ant-depalma
  • 2,006
  • 4
  • 26
  • 34

1 Answers1

0

To match the PasswordDeriveBytes in java use the PasswordDeriveBytes(extending org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator) from this stackoverflow answer.

But this works only for key under 20 byte!; This is the code to generate the key:

String text="marcoS";
String keyPhrase="password123";
byte[] salt={ 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 };

PasswordDeriveBytes generator = new PasswordDeriveBytes(new SHA1Digest());
generator.init(keyPhrase.getBytes("ASCII"), salt, 100);
byte[] key = ((KeyParameter) generator.generateDerivedParameters(KeySize)).getKey();    

Alternatively replace in dotNet the PasswordDeriveBytes with Rfc2898DeriveBytes.

To print bytes unsigned(for match with .net) use:

private static void printByteArray(byte[] arr) {
    if(arr == null || arr.length == 0){
        logger.debug("Array vuoto");
        return;
    }
    StringBuilder sb = new StringBuilder();
    for(byte b : arr)   {
        int x = b;
        if(x<0){
            x+=256;
        }
        sb.append("["+x+"] ");
    }
    logger.debug(sb.toString());
}
Community
  • 1
  • 1
Marco S.
  • 512
  • 2
  • 6
  • 22