Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

byte to char conversion in one time pad encryption program

Posted on 2006-04-18
15
Medium Priority
?
491 Views
Last Modified: 2009-12-16
i'm writing a simple one time pad encryption program, but having one last little problem.  I have a text file that contains the string "GinaTravis326" (w/o the quotes of course).   My dilemma is with the output.  Here are the steps I'm taking ...

(1)  pulled in the byte values into a plain text byte array (pText)
      **result:
          pText = [105, 110, 97, 84, 114, 97, 118, 105, 115, 51, 50, 54]

(2)  generated bits and stored them in a stringbuffer (bitSB); cycled through stringbuffer to create pad byte array via:
      (bitstring is a String variable, twoscomp computes the two's complement, and counter is an int initialized to 0)

for (int i=0; i<bitSB.length(); i+=8);
{
     bitstring = bitSB.substring(i, i+8);
     pad[counter++] = (byte)Integer.parseInt(twoscomp(bitstring));
}

    **result:
       pad = [31, -53, -81, -11, -56, 65, 24, 59, -47, 22, -127, -112, 18]

(3) I then use the bitwise XOR to populate a cipher text byte array (cText) & write to an encrypted output file via:

PrintWriter outfile = new PrintWriter(new FileOutputStream(file));
int cnt = 0;
while (cnt < pad.length)
{
     cText[cnt] = (byte)(pText[cnt]^pad[cnt]);
     outfile.print((char)cText[cnt]);
     cnt++;
 }

     **result:
         cText = [88, -94, -63, -108, -100, 51, 121, 77, -72, 101, -78, -94, 36]

----> NOW DECRYPTING <------

(4)  like before, i pull in the byte values from the file (which should be synonymous with cText)
(5)  create the pad byte array like before based of the cText values this time rather than the pText ones
(6)  did the bitwise XOR like about in step 3, except this time:

while (cnt < pad.length)
{
      pText[cnt] = (byte)(cText[cnt]^pad[cnt]);
      outfile.print((char)pText[cnt]);                    //this is not writing the correct characters to the decrypted file!
      cnt++;
}
                   
     **result:
         pText = [71, -12, -112, -54, -9, 114, 97, 118, -18, 115, -66, -81, 54]

When I cast the pText values back to (char) as shown above,
the decrypted file contains the string:
       G????rav?s??6
rather than
       GinaTravis326

It seems obvious to me that this is because of the negative values, but how do I account for this ???   How can I get the output to be correct???   Thanks !!!    

By the way, using the String(byte[], "UTF8").toCharArray() method is NOT an option.   Thanks again!

- Travis
0
Comment
Question by:trs28
  • 7
  • 5
  • 3
15 Comments
 
LVL 14

Accepted Solution

by:
Tommy Braas earned 700 total points
ID: 16483073
Do not use character based I/O. View everything as binary data.
0
 

Author Comment

by:trs28
ID: 16483143
Could you elaborate on that a little bit ??  ...maybe with an example or something!   I have a feeling what you're suggesting would make me have to "reinvent the wheel" here, but I'm just as in the dark as I was before I read that comment.  

Thanks
0
 
LVL 92

Assisted Solution

by:objects
objects earned 1300 total points
ID: 16483584
he means don't convert them to chars/strings, instead deal with the bytes directly.
When you convert between a string and byte array data conversion takes place according to (in your case) the default character encoding. This process may not be reversible.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:trs28
ID: 16483618
Once again, would it be possible to give me an example?  Or would I just remove the (char) section of the line that I write the file with??  Seriously guys, I wasn't mentioning it earlier to watch myself type!   lol   Thanks!
0
 

Author Comment

by:trs28
ID: 16483626
Please make sure you don't get too off track with your (everybody's) suggestions.  I'm sure there are much better ways of doing this, but I need to do this in the manner I described above, so I'm just looking how to account for the problem I'm having.  

0
 
LVL 92

Expert Comment

by:objects
ID: 16483668
OutputStream outfile = new FileOutputStream(file);
int cnt = 0;
while (cnt < pad.length)
{
     cText[cnt] = (byte)(pText[cnt]^pad[cnt]);
     outfile.write(cText[cnt]);
     cnt++;
 }

similiar to read it back in
0
 

Author Comment

by:trs28
ID: 16483817
I think you've got something going on with that idea....

now my output is ...

Ginè›ravis326


What could be causing the è and › rather than a and T respectively ????   So close!  :)
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 16483839
Sorry for not getting back sooner, had meetings...
Use InputStream and OutputStream as your I/O basis. FileInputStream, FileOutputStream.
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 16483842
Make sure that you're not casting to 'char' anywhere.
0
 

Author Comment

by:trs28
ID: 16483886
nope - that's not it - i'm not casting to char anywhere, yet the output is still with those two odd characters that i mentioned above.  

any other ideas?  

hell, was thinking about pasting the entire class for you to take a look at, but it is 220 lines or so.   i have a feeling an error like this would have to be "seen" rather than described.  i can always paste it though if need be!   i think it's almost there though!
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 16483946
If you post the code here, it is easier for people to refer to the solution. Another solution is to upload it somwhere and post the link here.
0
 

Author Comment

by:trs28
ID: 16484004
// Driver:
//            public class OTP
//            {
//                  public static void main(String[] args)
//                  {
//                         OneTimePadCipher c = new OneTimePadCipher();
//                  }
//
//            }

import java.util.*;
import java.io.*;

public class OneTimePadCipher
{
      private int numberOfBytes;
      private byte[] pText;
      private byte[] cText;
      private byte[] pad;
      
      private int numberOfBits;
      private StringBuffer bitSB;

      public OneTimePadCipher() throws InputMismatchException
      {
            Scanner consoleScan = new Scanner(System.in);
      
            int choice = 0;
            String filename = "";
            
            while (choice != 3)
            {
                  System.out.println("Encryption/Decryption Program");
                  System.out.printf("%11s%n", "1. Encrypt");
                  System.out.printf("%11s%n", "2. Decrypt");
                  System.out.printf("%8s%n", "3. Exit");
                  System.out.println();
                  System.out.printf("%9s", "Choice: ");
                  choice = consoleScan.nextInt();
                  
                  switch (choice)
                  {
                  case 1:
                        System.out.printf("%18s", "File to encrypt: ");
                        filename = consoleScan.next();
                        fetchMessage(filename, true);                                                                  
                        System.out.printf("%38s", "Encrypting ...saved as \"encrypt.txt\"" + "\n");
                        createOneTimePad();
                        transformMessage("encrypt.txt", true);
                        break;
                  case 2:
                        System.out.printf("%18s", "File to decrypt: ");
                        filename = consoleScan.next();
                        fetchMessage(filename, false);
                        System.out.printf("%38s", "Decrypting ...saved as \"decrypt.txt\"" + "\n");
                        createOneTimePad();
                        transformMessage("decrypt.txt", false);
                        break;
                  default:
                        System.out.println();
                        System.out.println("(program terminated)");
                        System.exit(0);
                  }
                  System.out.println();
            }
      }
      
      public void fetchMessage(String file, boolean encrypt)
      {
            FileInputStream fs = null;
            InputStreamReader isr = null;
            BufferedReader fileBR = null;
            int posindex = 0;
            int brValue = 0;
            
            try{
                  fs = new FileInputStream(file);
                  isr = new InputStreamReader(fs);
                  fileBR = new BufferedReader(isr);
                  numberOfBytes = fs.available();
            }catch(FileNotFoundException e){
                  System.out.println(" \"" + file + "\" not found.  Please try again.");
                  System.out.println();
                  new OneTimePadCipher();
            }catch(IOException e){
                  System.out.println(e.getLocalizedMessage());
            }
            
            if (encrypt)
            {
                  pText = new byte[numberOfBytes];
                  posindex = 0;
                  try{
                        brValue = fileBR.read();
                        while (brValue != -1)
                        {
                              pText[posindex++] = (byte)brValue;
                              brValue = fileBR.read();
                        }
                  }catch (IOException e){}
            }
            else
            {
                  cText = new byte[numberOfBytes];
                  posindex = 0;
                  try{
                        brValue = fileBR.read();
                        while (brValue != -1)
                        {
                              cText[posindex++] = (byte)brValue;
                              brValue = fileBR.read();
                        }
                  }catch (IOException e){}
            }
            
            numberOfBits = numberOfBytes * 8;
            bitSB = new StringBuffer(numberOfBits);
            
            try{
                  fs.close();
            }
            catch(IOException e){}
      }
      
      public void createOneTimePad()
      {
            String bitstring = "";
            int counter = 0;      //counter to increment an array seperately within a for loop
            
            generateBits(numberOfBits, bitSB);
            pad = new byte[numberOfBytes];
            for (int i=0; i<bitSB.length(); i+=8)  //cycles 8 bits at a time
            {
                  bitstring = bitSB.substring(i, i+8);
                  pad[counter++] = (byte)Integer.parseInt(twoscomp(bitstring));
            }
      }
      
      private void transformMessage(String file, boolean encrypt)
      {
            FileOutputStream os = null;
            try
            {
                  os = new FileOutputStream(file);
            }
            catch (FileNotFoundException e)
                  {
                        System.out.println(e.getMessage());
                  }            
            
            int cnt = 0;
            try{
                  if (encrypt)
                  {
                        cText = new byte[pText.length];
                        while (cnt < pad.length)
                        {
                              cText[cnt] = (byte)(pText[cnt]^pad[cnt]);
                              os.write(cText[cnt]);
                              cnt++;
                        }
                        cnt = 0;
                  }
                  else
                  {
                        pText = new byte[cText.length];
                        while (cnt < pad.length)
                        {
                              pText[cnt] = (byte)(cText[cnt]^pad[cnt]);
                              os.write(pText[cnt]);
                              cnt++;
                        }
                        cnt = 0;
                  }
            }catch(IOException e){}
            
            try{
                  os.close();
            }catch(IOException e){}
            
      }
      
      private String twoscomp(String s)
      {
            char[] ones = s.toCharArray();
            
            for (int i=0; i<ones.length; i++)
            {
                  if (ones[i] == '0')
                        ones[i] = '1';
                  else if (ones[i] == '1')
                        ones[i] = '0';
            }
            
            int backcount = ones.length-1;      
  twos:      while (backcount >= 0)
            {
                  if (ones[backcount] == '1')
                        ones[backcount] = '0';
                  else if (ones[backcount] == '0')
                  {
                        ones[backcount] = '1';
                        break twos;
                  }
                  backcount--;
            }

            return new String(ones);
    }
      
      private void generateBits(int n, StringBuffer rb)
      {
        boolean b[] = new boolean[11];

        b[10] = false; b[9] = true;  b[8] = true;  b[7] = false;
        b[6] = true;   b[5] = false; b[4] = false; b[3] = false;
        b[2] = false;  b[1] = true;  b[0] = false;

        for (int i=0; i<n; i++)
        {
            boolean bit = b[8] ^ b[10];
            b[10] = b[9]; b[9] = b[8]; b[8] = b[7];
            b[7] = b[6];  b[6] = b[5]; b[5]  = b[4];
            b[4] = b[3];  b[3] = b[2]; b[2] = b[1];
            b[1] = b[0]; b[0] = bit;

            if (bit) rb.append("1");
            else     rb.append("0");
        }
     }
}
0
 
LVL 92

Expert Comment

by:objects
ID: 16484056
>                fileBR = new BufferedReader(isr);

don't use a Reader

where you are using fileBR to read, instead use fs.
eg.

brValue = fs.read();
0
 

Author Comment

by:trs28
ID: 16484081
You guys are great!
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 16484611
;-D
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
In this post we will learn different types of Android Layout and some basics of an Android App.
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
Suggested Courses
Course of the Month11 days, 6 hours left to enroll

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question