Search code examples
javac#encryptionbase64

Same encryption algorithm in c# and java produces different output


I have C# code to encrypt password. I want to convert it to java. The converted java code produces different encrypted string than c#. What can i do so that output is same for both java and c#.

Password: Hello World2

C# output: orc_Aup5rLQZ_vB5atFuqw2

Java output: orc_Aup5rLQZ_vB5atFuqw==

C# code

    using System;
        using System.IO;
        using System.Security.Cryptography;
        using System.Text;
        using System.Web;
        
        namespace Crypto.Client
        {
            /// <summary>
            ///     Helper functions to encrypt and decrypt stuff
            /// </summary>
            public static class CryptoHelper
            {
                private static readonly byte[] Key =
                    {
                        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12,
                        0x13, 0x14, 0x15, 0x16
                    };
        
                private static readonly byte[] InitializationVector =
                    {
                        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
                        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
                    };
        
                //Encrypts the input string using a .net function.
                public static string Encrypt(string plainText)
                {
                    var rmCrypto = new RijndaelManaged();
                    using (var memoryStream = new MemoryStream())
                    {
                        using (
                            var cryptoStream = new CryptoStream(
                                memoryStream, rmCrypto.CreateEncryptor(Key, InitializationVector), CryptoStreamMode.Write))
                        {
                            using (var streamWiter = new StreamWriter(cryptoStream))
                            {
                                streamWiter.Write(plainText);
                            }
                        }
                        return HttpServerUtility.UrlTokenEncode(memoryStream.ToArray());
                    }
                }
            }
        }

Java code:

public class CryptoHelper
{
    private static final byte[] Key =
    {
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12,
        0x13, 0x14, 0x15, 0x16
    };

    private static final byte[] InitializationVector =
    {
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
    };
    
    public static String Encrypt(String plainText) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(Key, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(InitializationVector);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        CipherOutputStream cryptoStream = new CipherOutputStream(outputStream, cipher);
        cryptoStream.write(plainText.getBytes("UTF-8"));
        cryptoStream.close();
        
        byte[] encryptedBytes = outputStream.toByteArray();

        
        return Base64.getUrlEncoder().encodeToString(encryptedBytes);
    }
}

Solution

  • As mention in the comment by @topaco HttpServerUtility.UrlTokenEncode replaces padded bytes(=) with a number that equals the number of padding bytes. So I created a method to do this in java.

    https://stackoverflow.com/a/55426707/4498738