Nikson Kanti Paul
Nikson Kanti Paul

Reputation: 3440

C# and Java DES Encryption value are not identical

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.

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?

Upvotes: 2

Views: 6068

Answers (3)

Nikson Kanti Paul
Nikson Kanti Paul

Reputation: 3440

The problem was in mode of encryption.

SunJCE provider uses ECB as the default mode, and PKCS5Padding 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 is CipherMode.CBC and default padding is PaddingMode.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.

Upvotes: 9

user3874700
user3874700

Reputation:

The code (Java/Android) bellow worke for me. I used the same approach on C#.

public static String Cripto(String Password)
{
    String PasswordCripto = "";
    try
    {
        String encryptionKey = "anyEncryptionString";
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(encryptionKey.getBytes("UTF-8"), 0, encryptionKey.length());
        byte[] encryptionKeyBytes = messageDigest.digest();

        SecretKeySpec Key = new SecretKeySpec(encryptionKeyBytes,"DESede");
        Cipher cipher = Cipher.getInstance("DESEDE/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, Key);
        byte[] encryptedBytes = cipher.doFinal(Password.getBytes("UTF-8"));

        PasswordCripto = new String(Base64.encode(encryptedBytes, Base64.DEFAULT), "UTF-8");
    } catch(Exception e) { }
    return PasswordCripto ;
}

Upvotes: 0

SLaks
SLaks

Reputation: 887469

You're probably seeing ISO 10126 padding, which appends random bytes to the plaintext to fill it up t oa multiple of the block size.
This behavior is by design.

Upvotes: 1

Related Questions