-3

Trying to create java class which will encrypt and decrypt as like C# code in below.

Below is my code for C#, I need to convert it to Java. Can someone help me how to do it?

I've been doing this for almost 2 days yet can't find any solutions on how to convert it. I am new to crypto.

Note - It seems C# code used ACME libraries. But in my java, i should not use ACME jar files.

public static string EncryptBase64(string key, string clearText)
    {
        if (key.Length > 8)
            key = key.Substring(0, 8);

        byte[] keyBytes = System.Text.Encoding.ASCII.GetBytes(key);
        byte[] clearBytes = GetClearTextBytes(clearText);

        // calculate the number of legitimate bytes in the last block
        byte lastByte = (byte)(8 - (clearBytes.Length - textEncoding.GetByteCount(clearText)));

        MemoryStream ms = new MemoryStream();

        DES des = new DESCryptoServiceProvider();
        des.Padding = PaddingMode.None;
        des.GenerateIV();

        System.Security.Cryptography.ICryptoTransform ict = des.CreateEncryptor(keyBytes, des.IV);
        CryptoStream cs = new CryptoStream(ms, ict, CryptoStreamMode.Write);
        cs.Write(clearBytes, 0, clearBytes.Length);
        cs.FlushFinalBlock();
        ms.Close();

        byte[] cipherBytes = ms.ToArray();

        // create a byte output stream for Acme compatibality
        MemoryStream acmeCompatStream = new MemoryStream();

        // Acme writes the IV to the frist block
        acmeCompatStream.Write(des.IV, 0, 8);

        for (int i = 0; i < cipherBytes.Length; i = i + 8)
        {
            // write the next block
            acmeCompatStream.Write(cipherBytes, i, 8);

            // write the number of valid bytes in the block
            if (i == cipherBytes.Length - 8)
                acmeCompatStream.WriteByte(lastByte);
            else
                acmeCompatStream.WriteByte(8);
        }

        acmeCompatStream.Close();

        cipherBytes = acmeCompatStream.ToArray();

        return (System.Convert.ToBase64String(cipherBytes));
    }

Below is the code which i have tried in java. I have two different encryption function. I have tried both of the encryption method. But both are not giving expected encrypted string to decrypt in acme.

    package com.abc.some.common.nativeDES;

    import java.io.ByteArrayOutputStream;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.xml.bind.DatatypeConverter;

public class DESEncrypt {
    public String keyValue = "123456789";
    public static void main(String[] args) {
        String text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><SomeRequest><OrderNumber>1564578</OrderNumber></SomeRequest>";
        String codedtext ="not encrypted";
        try{
            codedtext = new DESEncrypt().Encrypt1(text);
            //codedtext = new DESEncrypt().encrypt(text);
        }catch (Exception e) {
            System.out.println("Exception in Encryption.. " + e.getMessage());
        }

        System.out.println(codedtext);

    }
    public String Encrypt1(String CXML) {
        try {
            KeySpec myKey = new DESKeySpec(keyValue.getBytes("UTF8"));
        SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(myKey);
        Cipher ecipher = Cipher.getInstance("DES");
        ecipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] data = CXML.getBytes("ASCII");

        Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
        c.init(Cipher.ENCRYPT_MODE, key);

        byte[] crypt = ecipher.doFinal(data);
        //String encoded = DatatypeConverter.printBase64Binary(crypt.toString().getBytes("ASCII"));
        //String encoded = DatatypeConverter.printBase64Binary(crypt.getBytes("ASCII"));

        String encoded = DatatypeConverter.printBase64Binary(crypt).toString();

        System.out.println(encoded);

        return encoded;
        } catch (Exception ex) {
        }

        return null;
    }    
}

But I have used below java file to encrypt the string which is using acme jar files. This was working as expected. But as per my project requirement i should not use the external(ACME) jar files.

package com.abc.common.encryption;

import java.io.FileInputStream;
import java.util.Properties;
import Acme.Crypto.SecurityDES;

public class ESBCryptoDES {

    public static void main(String args[]){
//      DESEncrypt("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><SomeRequest><OrderNumber>1564578</OrderNumber></SomeRequest>"
//              ,"D:\\name\\proj\\order\\Encryption\\st.properties");
        DESDecrypt("vQ9C7ZrLzjQpHvZjtHvUb0mFCr824/aClY2jKbeciczsRVr+kEETFvDuHgdBS/aLskYV3WX3U5TANSlK3pH80r3xOyn9Q8rTjlB/yXyU7J9MgibJ66jJx0wrqeloAkmQzqj+b5+I/lXANSlK3pH80kT1D+jqWAeV"
                ,"D:\\name\\proj\\order\\Encryption\\stDecrypt.properties");
    }
    public static String DESEncrypt(String SourceStrForCrypt,String PropPath) {
        String encrypt = "";
        String decrypt = "";
        // Load the property file.
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(PropPath);
            prop.load(in);
            in.close();
        } catch (Exception e) {
            System.out.println("Exception in loading property file.. "
                    + e.getMessage());
        }

        // Encrypt the given content.
        try {
            String keypath = prop.getProperty("proj.sample.DEV");
            System.out.println("sample" + keypath);

            String SourceToEncrypt = SourceStrForCrypt; //This will provide the xml string to encrypt
            // Encryption
            encrypt = SecurityDES.DesEncryptBase64(keypath,SourceToEncrypt);
            System.out.println(encrypt);
            // Decryption
            decrypt = SecurityDES.DesDecryptBase64(keypath, encrypt);
            System.out.println(decrypt);

        } catch (Exception e) {
            System.out.println("Exception in Encryption.. " + e.getMessage());
        }
        return encrypt;
    }

    public static String DESDecrypt(String SourceStrForCrypt,String PropPath) {
        // TODO Auto-generated method stub
        String decrypt = "";

        Properties prop = new Properties();

        try {
            FileInputStream in = new FileInputStream(PropPath);
            prop.load(in);
            in.close();
        } catch (Exception e) {
            System.out.println("Exception in loading property file.. "+ e.getMessage());
        }

        try {
            String abc_keyPath = prop
                    .getProperty("proj.abc.DEV");
            System.out.println("keypath" + abc_keyPath);
            // Decryption
            decrypt = SecurityDES.DesDecryptBase64(abc_keyPath, SourceStrForCrypt);
            System.out.println("decrypted..."+decrypt);

        } catch (Exception e) {
            System.out.println("Exception in Encryption.. " + e.getMessage());
        }
        return decrypt;

    }
}
Simbu
  • 766
  • 1
  • 12
  • 37
  • Show us what you tried, and tell us precisely what the problem is. – JB Nizet Mar 08 '17 at 07:20
  • StackOverflow isn't a code conversion service. And you shouldn't use DES. – Luke Joshua Park Mar 08 '17 at 08:27
  • If you're using ACME to mean built-in, aka you're supposed to write DES yourself (presumably, as homework), then see [FIPS PUB 46(-3)](http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf) for the algorithm and [NIST SP 800-17](http://ws680.nist.gov/publication/get_pdf.cfm?pub_id=151177) (Appendix A) for test validation. -- If you're not supposed to write DES yourself, you need to at least explain what wrong answers you've come up with. – bartonjs Mar 08 '17 at 15:42
  • @JBNizet .. I apologise for not sharing about my java work which i have tried. Updated my question with java code which i have tried. Could you show some light what went wrong in my java code. – Simbu Mar 09 '17 at 05:17

1 Answers1

1
  • Calling doFinal() twice doesn't make sense.
  • Printing the value of byte[].toString() doesn't make sense. It doesn't contain the ciphertext.
  • Converting that to base-64 doesn't make sense. It still doesn't contain the ciphertext.

You need to convert the byte[] array returned by the first doFinal() call directly to base-64, without the round-trip to and from String() caused by calling toString() and then `getBytes().

NB For some reason you have a variable called encrypt in your decrypt method, and for some even stranger reason you are returning it instead of decrypt, which is the only variable that actually contains plaintext.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I have updated my code as per your comments. Still when i call base64 without converting to string, throws me an error. I have tried like below statement. //String encoded = DatatypeConverter.printBase64Binary(crypt.toString().getBytes("ASCII")); String encoded = DatatypeConverter.printBase64Binary(crypt.getBytes("ASCII")); – Simbu Mar 09 '17 at 06:10
  • Sigh. Please think before typing. `crypt` *already is* a `byte[]`. I *specifically said* to 'convert it *directly* to base-64'. You don't have to do anything to get it as a `byte[]`. And you can't. The compiler just told you that. NB it didn't 'throw you an error'. Compiler messages are printed, not thrown. Exception are thrown at runtime. Be clear in your thinking, and in what you report here. – user207421 Mar 09 '17 at 06:25
  • I accept my fault and updated my java code as per your comments. Tried some thing like below. String encoded = DatatypeConverter.printBase64Binary(crypt).toString(); Now i got some encrypted string and i have tried to decrypt same using ACME jar classes and it throws me an error saying "encrypted byte length: 120 invalid ciphertext bytecount" – Simbu Mar 09 '17 at 07:22
  • What is the output type of `DatatypeConverter.printBase64Binary()`? And why does it need to be converted to a `String`? – user207421 Mar 09 '17 at 10:56
  • Removed the String conversion and it is not required as you have mentioned. – Simbu Mar 13 '17 at 05:36