0
votes

I created a simple java chat application . Below is the follow

Run ChatClient.java - Dialog box is shown where user enters username. Then private key and public key are generated and stored in C:/username/publickey,C:/username/privatekey.

Above step repeats when we run ChatClient.java again.

Then user1 sends message to User2 in encrypted form using User2 public key (Which is working fine)(after encryption , message is stored in text file) then User2 clicks decrypt button which decrypts the text (reads the encrypted text from file) using User 2 private key then display in textarea.

When I trying to decrypt I am getting "Not PKCS#1 block type 2 or Zero padding" exception

public static byte[] encrypt(String text, PublicKey key) throws {
    // get an RSA cipher object and print the provider
    final Cipher cipher = Cipher.getInstance(ALGORITHM);
    // encrypt the plain text using the public key
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] cipherText = cipher.doFinal(text.getBytes("UTF8"));
    return org.apache.commons.codec.binary.Base64.encodeBase64(cipherText);
}

public static String decrypt(String text, PrivateKey key) throws  {
    byte[] dectyptedText = null;

      // get an RSA cipher object and print the provider
      final Cipher cipher = Cipher.getInstance(ALGORITHM);

      // decrypt the text using the private key
     cipher.init(Cipher.DECRYPT_MODE, key);
     byte[] byteCipherText =org.apache.commons.codec.binary.Base64.decodeBase64(text): 
     byte[] cipherData = cipher.doFinal(byteCipherText);
     return new String(dectyptedText);  
}

private void btnDecryptActionPerformed(ActionEvent evt) throws  {
    String name11 = this.getTitle();
    String test90 = null;
    String PRIVATE_KEY_FILE = "C:/keys/"+name11+"/private.key";
    BufferedReader in = null;
    try {
        in = new BufferedReader(new FileReader("cipher.txt"));
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
        while(in.ready())
        {
            String stest= in.readLine();
            test90 = stest;


        }
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    ObjectInputStream inputStream = null;
    try {
    inputStream = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    PrivateKey privateKey = null;
    try {
        privateKey = (PrivateKey) inputStream.readObject();
    } catch (ClassNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
    inputStream = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        PrivateKey privatekey = (PrivateKey) inputStream.readObject();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    String plainText;

//  byte[] test100 = test90.getBytes();
//  out.println(test100);
    plainText = decrypt(test90, privateKey); (Getting Error Here)
    decryptText.append(plainText);
} 
1
Another tip along the lines of anonymous: Before engaging yourself with the decryption problems you should make sure that right before the decryption call you have the exact same binary data in a variable (in your case byteCipherText) that was generated by the encryption call (in your case cipherText). To do that you can for example compare a hash (as in sha256) of these byte arrays and if they don't match look for problems in the transmission code first. - Perseids
Do is the encoding correct? I am using Base64 encoding to ensure it properly written to file and then read back. Is there any way I can store encryptedtext in global variable and access later or broadcast to server and read it later ? instead of w/r from file - user3567218

1 Answers

1
votes

The highlighted code below means test90 only contains the last line in the cipher.txt file. Does cipher.txt contain 1 line only? If you want to read in everything, you need to concatenate each line as you read it in.

while(in.ready())
{
    String stest= in.readLine();
    test90 = stest;
}

It is also a good idea to System.out the variable test90 in the decrypt method to be sure that you're getting the expected base64 data to be decrypted.