This discussion is archived
7 Replies Latest reply: May 6, 2013 11:05 AM by capagira87 RSS

Re: The difference between update() and doFinal() in ClassCipher

capagira87 Newbie
Currently Being Moderated
Hi Guys,
I found this topic,
The difference between update() and doFinal() in ClassCipher
during a Google Search. I need your help, because I'm working on a project for an university exam.
It's about a Client FTP that sends and received files with the content crypted.
I'm using DES Encryption with "DES/CBC/PKCS5Padding".
I have this doubt: when it's correct to uso the doFinal method? At the last block of the file, or after it? (for encryption)
And during the decryption, how can I use the result of the doFinal operation?
  • 1. Re: The difference between update() and doFinal() in ClassCipher
    safarmer Expert
    Currently Being Moderated
    I have this doubt: when it's correct to uso the doFinal method? At the last block of the file, or after it? (for encryption)
    If you have all data in a buffer, just call doFinal(buffer). If you know you have the last block call doFinal(lastBlock) with all previous blocks being sent to update(). If you do not know until after call doFinal(). Given this is a javacard forum, the only doFinal() takes a buffer so you should call it with the last block. The last block can also be the first block in which case you do not call update.
    And during the decryption, how can I use the result of the doFinal operation?
    How ever you want. Once you call doFinal() the result is the plain text.

    I have a feeling this thread should be in the cryptography section of the forum though.

    - Shane
  • 2. Re: The difference between update() and doFinal() in ClassCipher
    capagira87 Newbie
    Currently Being Moderated
    Thank you for your reply. I'm sorry if this topic is in the wrong section, but I found it already here.
    However I applied this suggestion and many times my code doesn't make a good decryption. On the output file (that is a txt file) I have a string like this: "¬í z 4 bÿý Aÿýÿýÿýÿýÿý ÿýÿýÿýÿý sÿýÿýÿý e ÿýÿýÿý ,ÿýÿý ] x +ÿý K f      I <ÿý , ÿýÿýÿýÿý @ÿý Mÿý @ÿý ?ÿýÿýÿý p      hÿýÿý ~ÿý 3 tÿýÿýÿý Kÿý " jÿý % Zÿý ÿý K ÿýÿýÿýÿý Nÿýÿýÿýÿý Jÿý w Kÿý p nÿýÿýÿý s %ÿý $ÿýÿýÿý Aÿýÿý ".

    Where there could be the error? Maybe in the initialisation of the Cipher?
  • 3. Re: The difference between update() and doFinal() in ClassCipher
    safarmer Expert
    Currently Being Moderated
    To be able to help, I would need to see your code. It could be the cipher, it could be how you are handling the bytes, it could be how you encode the string. If you post a short working example I can look at it.

    - Shane
  • 4. Re: The difference between update() and doFinal() in ClassCipher
    capagira87 Newbie
    Currently Being Moderated
    Ok these are the functions:

    public void CodificaInvia (String cd, String filename, SecretKey Key) // it opens, codes and sends to the server the content of the file 512 bytes per time
    {
    int returncode=0;
    Socket DataSock = null;
    FileInputStream fis = null;
    byte [] text = null;
    try {
    DataSock = new Socket (servAddress,22);
    ObjectInputStream cin = new ObjectInputStream (DataSock.getInputStream());
    ObjectOutputStream out = new ObjectOutputStream (DataSock.getOutputStream());
    byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 0x07, 0x72, 0x6F, 0x5A };
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, Key, paramSpec);
    fis = new FileInputStream (cd+File.separator+filename);
    int size = fis.available();
    if ((size%8)==0)
    {
    text = new byte [size];
    } else {
    do {
    size++;
    } while ((size%8)!=0);
    text = new byte [size];
    }
    fis.read(text,0,fis.available());
    byte [] ciphertext = cipher.doFinal(text);
    out.writeInt(ciphertext.length);
    int numblock = ciphertext.length/512;
    int resto = ciphertext.length%512;
    out.writeInt(numblock);
    out.writeInt(resto);
    byte [] tempblock = new byte [512];
    for (int conta=0; conta<numblock; conta++)
    {
    for (int i=0; i<512; i++)
    {
    tempblock=ciphertext[(conta*512)+i];
    }
    out.write(tempblock);
    out.flush();

    }
    if (resto > 0) // this block works if the file size is not multiple of 512
    {
    java.util.Arrays.fill (tempblock, (byte) 0);
    int h= numblock*512;
    for (int i=0; i<resto; i++)
    {
    tempblock[i]=ciphertext[h+i];
    }
    out.write (tempblock);
    out.flush();
    }
    System.out.println ("OK!");
    } catch (Exception e)
    {
    e.printStackTrace();
    }

    }

    public void RicezioneDecodifica (String filename, SecretKey Key) // in this function I receive the file blocks, I decrpyt them and I save the decrypted text into a file
    {
    Socket DataSock = null;
    byte [] buffer=null; // it saves the received data
    String Plaintext = new String (); // it saves the deciphered text
    try {
    ServerSocket ss2 = new ServerSocket (TRANSMISSION_PORT);
    DataSock = ss2.accept();
    ObjectOutputStream out = new ObjectOutputStream (DataSock.getOutputStream());
    ObjectInputStream cin = new ObjectInputStream (DataSock.getInputStream());
    byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 0x07, 0x72, 0x6F, 0x5A };
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
    Cipher dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    dcipher.init(Cipher.DECRYPT_MODE, Key, paramSpec);
    int size = cin.readInt();
    int numblock = cin.readInt();
    int resto = cin.readInt();
    if ((size%8)!=0)
    {
    do{
    size++;
    } while ((size%8)!=0);
    }
    int ByteLetti=0; // counter of read bytes
    buffer = new byte [size];
    for (int conta=0; conta<numblock; conta++)
    {
    int a=cin.available();
    byte [] tempblock = new byte [a];
    cin.read(tempblock, 0, a);
    for (int i=0; i<a; i++)
    {
    buffer[ByteLetti+i]=tempblock[i];
    }
    ByteLetti=ByteLetti+a;
    byte[] texttmp=dcipher.update(tempblock);
    String tmp = new String (texttmp, "UTF8");
    Plaintext=Plaintext+tmp;
    }
    if (resto>0)
    {
    int a = cin.available();
    byte [] tempblock;
    if ((a%8)>0)
    {
    do {
    a++;
    } while ((a%8)!=0);
    tempblock = new byte [a];
    cin.read(tempblock, 0, cin.available());
    byte[] texttmp = dcipher.doFinal(tempblock);
    String tmp = new String (texttmp, "UTF8");
    Plaintext = Plaintext+tmp;
    }
    }
    ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream (filename));
    oos.writeChars(Plaintext);
    oos.flush();
    oos.close();
    } catch (Exception e)
    {
    e.printStackTrace();
    }
    }
  • 5. Re: The difference between update() and doFinal() in ClassCipher
    safarmer Expert
    Currently Being Moderated
    Reposting with &#123;code} tags
    capagira87 wrote:
    Ok these are the functions:
    public void CodificaInvia (String cd, String filename, SecretKey Key) // it opens, codes and sends to the server the content of the file 512 bytes per time
    {
    int returncode=0;
    Socket DataSock = null;
    FileInputStream fis = null;
    byte [] text = null;
    try {
    DataSock = new Socket (servAddress,22);
    ObjectInputStream cin = new ObjectInputStream (DataSock.getInputStream());
    ObjectOutputStream out = new ObjectOutputStream (DataSock.getOutputStream());
    byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 0x07, 0x72, 0x6F, 0x5A };
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, Key, paramSpec);
    fis = new FileInputStream (cd+File.separator+filename);
    int size = fis.available();
    if ((size%8)==0)
    {
    text = new byte [size];
    } else {
    do {
    size++;
    } while ((size%8)!=0);
    text = new byte [size];
    }
    fis.read(text,0,fis.available());
    byte [] ciphertext = cipher.doFinal(text);
    out.writeInt(ciphertext.length);
    int numblock = ciphertext.length/512;
    int resto = ciphertext.length%512;
    out.writeInt(numblock);
    out.writeInt(resto);
    byte [] tempblock = new byte [512];
    for (int conta=0; conta<numblock; conta++)
    {
    for (int i=0; i<512; i++)
    {
    tempblock=ciphertext[(conta*512)+i];
    }
    out.write(tempblock);
    out.flush();

    }
    if (resto > 0) // this block works if the file size is not multiple of 512
    {
    java.util.Arrays.fill (tempblock, (byte) 0);
    int h= numblock*512;
    for (int i=0; i<resto; i++)
    {
    tempblock[i]=ciphertext[h+i];
    }
    out.write (tempblock);
    out.flush();
    }
    System.out.println ("OK!");
    } catch (Exception e)
    {
    e.printStackTrace();
    }

    }

    public void RicezioneDecodifica (String filename, SecretKey Key) // in this function I receive the file blocks, I decrpyt them and I save the decrypted text into a file
    {
    Socket DataSock = null;
    byte [] buffer=null; // it saves the received data
    String Plaintext = new String (); // it saves the deciphered text
    try {
    ServerSocket ss2 = new ServerSocket (TRANSMISSION_PORT);
    DataSock = ss2.accept();
    ObjectOutputStream out = new ObjectOutputStream (DataSock.getOutputStream());
    ObjectInputStream cin = new ObjectInputStream (DataSock.getInputStream());
    byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 0x07, 0x72, 0x6F, 0x5A };
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
    Cipher dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    dcipher.init(Cipher.DECRYPT_MODE, Key, paramSpec);
    int size = cin.readInt();
    int numblock = cin.readInt();
    int resto = cin.readInt();
    if ((size%8)!=0)
    {
    do{
    size++;
    } while ((size%8)!=0);
    }
    int ByteLetti=0; // counter of read bytes
    buffer = new byte [size];
    for (int conta=0; conta<numblock; conta++)
    {
    int a=cin.available();
    byte [] tempblock = new byte [a];
    cin.read(tempblock, 0, a);
    for (int i=0; i<a; i++)
    {
    buffer[ByteLetti+i]=tempblock[i];
    }
    ByteLetti=ByteLetti+a;
    byte[] texttmp=dcipher.update(tempblock);
    String tmp = new String (texttmp, "UTF8");
    Plaintext=Plaintext+tmp;
    }
    if (resto>0)
    {
    int a = cin.available();
    byte [] tempblock;
    if ((a%8)>0)
    {
    do {
    a++;
    } while ((a%8)!=0);
    tempblock = new byte [a];
    cin.read(tempblock, 0, cin.available());
    byte[] texttmp = dcipher.doFinal(tempblock);
    String tmp = new String (texttmp, "UTF8");
    Plaintext = Plaintext+tmp;
    }
    }
    ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream (filename));
    oos.writeChars(Plaintext);
    oos.flush();
    oos.close();
    } catch (Exception e)
    {
    e.printStackTrace();
    }
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
  • 6. Re: The difference between update() and doFinal() in ClassCipher
    safarmer Expert
    Currently Being Moderated
    It would make it easier if you had two methods like you do, but one encrypting to a file, then another decrypting from the file. Then a main that allowed me to just run and see the results.

    Here is a simplified version of your code that should do much the same thing.

    Some comments:
    - You had code to get the padded size of the array and using PKCS#5 padding. This may have resulted in different cipher text than you were expecting
    - You were writing to the final file with a DataOutputStream and writing a string to it, where you actually have bytes that happen to be character data (maybe user Reader/Writer rather than stream?)
    - Your code was doing the heavy lifting that System.arraycopy() would do
    - Your code is converting the plain text to a String. This would assume only printable characters in the stream. As mentioned, maybe use Reader/Writer.
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.security.spec.AlgorithmParameterSpec;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    
    /**
     * TODO: Insert description here. (generated by safarmer)
     */
    public class StreamCipher {
      private final int TRANSMISSION_PORT = 22;
      private final byte[] iv = {(byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 0x07, 0x72, 0x6F, 0x5A};
      private final AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
      private final Cipher cipher;
    
      public StreamCipher() {
        try {
          cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        } catch (Exception e) {
          throw new IllegalStateException(e);
        }
      }
    
      // it opens, codes and sends to the server the content of the file 512 bytes per time
      public void CodificaInvia(String cd, String filename, SecretKey Key) {
        try {
          Socket dataSock = new Socket("127.0.0.1", TRANSMISSION_PORT);
          ObjectOutputStream out = new ObjectOutputStream(dataSock.getOutputStream());
    
          cipher.init(Cipher.ENCRYPT_MODE, Key, paramSpec);
          FileInputStream fis = new FileInputStream(new File(cd, filename));
    
          // If you use PKCS#5 padding you don't need to pad the file.
          byte[] text = new byte[fis.available()];
          fis.read(text);
    
          byte[] ciphertext = cipher.doFinal(text);
          out.writeInt(ciphertext.length);
          out.write(ciphertext);
          out.flush();
          System.out.println("OK!");
        } catch (Exception e) {
          e.printStackTrace();
        }
    
      }
    
      // in this function I receive the file blocks, I decrpyt them and I save the decrypted text into a
      // file
      public void RicezioneDecodifica(String filename, SecretKey Key) {
        try {
          ServerSocket ss2 = new ServerSocket(TRANSMISSION_PORT);
          Socket dataSock = ss2.accept();
          ObjectInputStream cin = new ObjectInputStream(dataSock.getInputStream());
    
          int size = cin.readInt();
          byte[] buffer = new byte[size];
          cin.read(buffer);
    
          cipher.init(Cipher.DECRYPT_MODE, Key, paramSpec);
          byte[] plain = cipher.doFinal(buffer);
          OutputStream os = new FileOutputStream(filename);
          os.write(plain);
          os.flush();
          os.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  • 7. Re: The difference between update() and doFinal() in ClassCipher
    capagira87 Newbie
    Currently Being Moderated
    Thank you for your useful help. However the code gives me the error: "Final block not properly padded" even if the text to decrypt is of 1768 byte. What does it depend of?

    I post here the function of the decryption:
    public void ReceiveDecryptStore (String filename, SecretKey Key)
        {
            try {
                Socket DataSock = null;
                ServerSocket ss2 = new ServerSocket (TRANSMISSION_PORT);            
                DataSock = ss2.accept();
                ObjectInputStream ois = new ObjectInputStream (DataSock.getInputStream());
                Cipher dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
                byte[] iv = {(byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 0x07, 0x72, 0x6F, 0x5A};
                AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
                dcipher.init(Cipher.DECRYPT_MODE, Key, paramSpec);
                int size = ois.readInt();
                byte [] encryptText = new byte [size];
                byte [] buffer = new byte [1024];
                int numblocks = size/1024;
                int resto = size %1024;
                for (int i=0; i<numblocks; i++)
                {
                    ois.read(buffer);
                    System.arraycopy(buffer, 0,encryptText , i*1024, 1024);
                }
                ois.read(buffer,0,resto);
                System.arraycopy (buffer,0,encryptText,1024*numblocks,resto);
                byte [] decipherText = dcipher.doFinal(encryptText);
                System.out.println ("OK code!");
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }