实现Bouncy Castle AES 256

3

我正在开发一个聊天应用程序。主要功能是以加密形式发送消息,当它们到达目的地时可以解密。我遇到的问题是,消息在到达目的地后无法解密,但它们以加密形式到达了目的地。

代码如何工作:

  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.

我的代码:

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);
  }
}

你的问题非常不具体,只是要求“通过编写代码来修复它使其正常工作”。你的问题格式非常糟糕,这让我认为你没有花太多时间在上面。你过度使用省略号也让我觉得你有些力不从心。尽可能多地在办公时间内与您的导师/助教交流,但由于落后太多而无法赶上,您仍然可能会失败。 - Nathaniel Waisbrot
我刚刚测试了你的加密/解密代码,它可以正常运行。你的问题必须出在其他地方。因此,我已经投票关闭了这个问题。 - Duncan Jones
注意:在发布代码示例之前,您真的应该测试一下。我花了两分钟才弄清楚代码是否正确运行。关于风格的一点说明:不要从方法中抛出Exception,而是只抛出必要的受检异常(IllegalStateException, InvalidCipherTextException)。 - Duncan Jones
我测试了这段代码,伙计,它运行得很好......但是当我在我的项目中使用这段代码时,我遇到了错误,字符串被加密了,但是无法解密......我将要加密的字符串传递给这个程序,然后在接收客户端结束时,我将加密的字符串传递给解密方法,但它不起作用...... - Syed Hassaan Ali
@SyedHassaanAli 不要这样做。我们不会在这个网站上修复整个项目。你尝试过我的建议吗?只是发送明文。另外,如果你在我的用户名前加上“@”符号,我将收到你的回复通知。 - Duncan Jones
显示剩余3条评论
1个回答

3
您经常使用String.getBytes()。这几乎是您犯错误的一个地方。 getBytes() 依赖于平台,因此在不同系统上可能会得到不同的字节。此外,并非所有字节都是有效的字符编码。因此,如果您的密钥/IV由安全随机字节组成(应该是),则解密有时会失败。
一般的解决方法是使用规范良好的字符编码(例如UTF-8)将字符转换为字节,使用像base-64或十六进制这样的编码将字节转换为字符。

谢谢你的帮助,伙计。我用这个代码 https://dev59.com/2mkv5IYBdhLWcg3w3Eal 替换了那个代码,现在它正常工作了。 - Syed Hassaan Ali
你可以从那里的被接受的答案中得到一些提示,特别是关于字符编码/解码方面的,但那里的代码并不安全。千万不要使用ECB模式。请尝试我的答案这里 - Maarten Bodewes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接