implementing bouncy castle aes 256

2019-05-16 21:03发布

问题:

I am working on a chat application. The main feature is to send messages in encrypted form and when they reach their destination they can be decrypted. The problem I am having is that the messages are not getting decrypted at their destination but however they reach their destination in encrypted form.

How the code works:

  1. Client A sends message "Hello" to client B...
  2. When Client A clicks on button "Send message" I save that text in a String and then that String is passed along with key and iv to the method Encrypt like this...

    en=enc.encrypt(msg.getBytes(), key.getBytes(), iv.getBytes());
    

    I convert that byte (en) into string and sends it to the other client B.

  3. When I open the other class where I receive the message I get the string (en) and then again converts it into bytes which is passed to the method Decrypt. But whenever I run the project it doesn't work. Tried to do that in try catch but didn't worked either. Maybe because it is already in a big try catch statement already which makes it even more confusing.

My code:

package com.socket;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;

public class Encrypt {

  public Encrypt() {
  }

  public static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
      throws Exception {
    int minSize = cipher.getOutputSize(data.length);

    byte[] outBuf = new byte[minSize];

    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);

    int length2 = cipher.doFinal(outBuf, length1);

    int actualLength = length1 + length2;

    byte[] result = new byte[actualLength];

    System.arraycopy(outBuf, 0, result, 0, result.length);

    return result;
  }

  public static byte[] decrypt(byte[] cipher, byte[] key, byte[] iv)
      throws Exception {

    PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(
        new CBCBlockCipher(new AESEngine()));

    CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);

    aes.init(false, ivAndKey);

    return cipherData(aes, cipher);
  }

  public byte[] encrypt(byte[] plain, byte[] key, byte[] iv) throws Exception {

    PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(
        new CBCBlockCipher(

        new AESEngine()));

    CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);

    aes.init(true, ivAndKey);

    return cipherData(aes, plain);
  }
}

回答1:

You are using String.getBytes() on a regular basis. That's almost certain one location where you make an error. getBytes() is platform dependent, so you may get different bytes on different systems. Furthermore, not all bytes are valid character encodings. So if your key/IV consists of secure random bytes (which they should) then your decryption will fail...sometimes.

The general answer is to convert characters to bytes using a well specified character-encoding (e.g. UTF-8) and bytes to characters using an encoding like base-64 or hexadecimals.