I am trying to encrypt the same data using C# and Java. If the data is more than 7 bytes then Java and C#’s encrypted value are not identical.
Input 1: a
java output: FrOzOp/2Io8=
C# output: FrOzOp/2Io8=Input 2: abc
j : H9A/ahl8K7I=
c#: H9A/ahl8K7I=Input 3: aaaaaaaa (Problem)
j : Gxl7e0aWPd7j6l7uIEuMxA==
c#: Gxl7e0aWPd7sf1xR6hK4VQ==
Here is the implementation of C# and Java methods.
C# code:
public String saltTxt = "12345678"; public String Encrypt(String txt) { byte[] data = Encrypt(Encoding.UTF8.GetBytes(txt)); DESCryptoServiceProvider alg = new DESCryptoServiceProvider(); alg.Key = Encoding.UTF8.GetBytes(saltTxt.ToCharArray(), 0, cprovider.KeySize / 8); alg.IV = new byte[8]; MemoryStream ms = new MemoryStream(); CryptoStream stem = new CryptoStream( ms, cprovider.CreateEncryptor(),CryptoStreamMode.Write); stem.Write(txt, 0, txt.Length); stem.FlushFinalBlock(); data = ms.ToArray(); return Convert.ToBase64String(data); }
Java Code:
public String saltTxt = "12345678"; public String Encrypt(String str) { try { KeySpec myKey = new DESKeySpec(saltTxt.getBytes("UTF8")); SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(myKey); Cipher ecipher = Cipher.getInstance("DES"); ecipher.init(Cipher.ENCRYPT_MODE, key); byte[] data = str.getBytes("UTF8"); byte[] crypt = ecipher.doFinal(data); return new BASE64Encoder().encode(crypt); } catch (Exception ex) { } return null; }
Any idea why it’s not working as expected?
Advertisement
Answer
The problem was in mode
of encryption.
SunJCE provider uses
ECB
as the default mode, andPKCS5Padding
as the default padding scheme for DES, DES-EDE and Blowfish ciphers. (JCA Doc)
and
In
.Net
, The default operation mode for the symmetric algorithm isCipherMode.CBC
and default padding isPaddingMode.PKCS7
. (msdn..SymmetricAlgorithm)
The following changes resolve the problem.
// in C# DESCryptoServiceProvider alg = new DESCryptoServiceProvider(); alg.Mode = CipherMode.ECB; // specified
or
// in java chiper = Cipher.getInstance("DES/CBC/PKCS5Padding");
don’t change in both sides.