gpt4 book ai didi

java - BouncycaSTLe in Java奇数加密解密结果

转载 作者:搜寻专家 更新时间:2023-11-01 03:39:21 30 4
gpt4 key购买 nike

所以我一直在使用 BouncycaSTLe 库来尝试连接远程服务器。这个过程从一开始就存在问题,现在我快要让一切正常工作了,但一些奇怪的事情正在发生。

当我第一次开始构建加密过程时,我被告知要使用 AES 256 和 PKCS7Padding。经过一番唠叨后,我得到了一个服务器代码的 C++ 示例。结果发现 IV 是 256 位,所以我不得不改用 RijndaelEngine。此外,为了使其正常工作,我必须使用 ZeroBytePadding。

这是我的代码:

 socket = new Socket(remoteIP, port);

outputStream = new PrintWriter(socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));

byte[] base_64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".getBytes("UTF-8");

Security.addProvider(new BouncyCastleProvider());

public String AESEncrypt(String out) throws IOException, DataLengthException, IllegalStateException, InvalidCipherTextException {
byte[] EncKey = key;
byte randKey;
Random randNumber = new Random();

randKey = base_64[randNumber.nextInt(base_64.length)];
EncKey[randKey&0x1f] = randKey;

RijndaelEngine rijndaelEngine = new RijndaelEngine(256);
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(rijndaelEngine), new ZeroBytePadding());
ParametersWithIV keyParameter = new ParametersWithIV(new KeyParameter(EncKey), iv);
cipher.init(true, keyParameter);

byte[] txt = out.getBytes();
byte[] encoded = new byte[cipher.getOutputSize(txt.length)];
int len = cipher.processBytes(txt, 0, txt.length, encoded, 0);

cipher.doFinal(encoded, len);

char keyChar = (char) randKey;
String encString = new String(Base64.encode(encoded));
encString = encString.substring(0, encString.length()-1) + randKey;

return encString;
}

public void AESDecrypt(String in) throws DataLengthException, IllegalStateException, IOException, InvalidCipherTextException {
byte[] decKey = key;
byte[] msg = in.getBytes();
byte randKey = msg[msg.length-1];
decKey[randKey&0x1f] = randKey;

byte[] trimMsg = new byte[msg.length-1];
System.arraycopy(msg, 0, trimMsg, 0, trimMsg.length);

in = new String(trimMsg);

RijndaelEngine rijndaelEngine = new RijndaelEngine(256);
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(rijndaelEngine), new ZeroBytePadding());
ParametersWithIV keyParameter = new ParametersWithIV(new KeyParameter(decKey), iv);
cipher.init(false, keyParameter);

byte[] encoded = Base64.decode(in.trim());
byte[] decoded = new byte[cipher.getOutputSize(encoded.length)];
int len = cipher.processBytes(encoded, 0, encoded.length, decoded, 0);
cipher.doFinal(decoded, len);

String decString = new String(decoded);
}

这是我用来发送和接收消息的测试函数:

 public void serverTest() throws DataLengthException, IllegalStateException, InvalidCipherTextException, IOException {

//out = AESEncrypt(out);

outputStream.write(out + "\n");
outputStream.flush();

String msg = "";

while ((msg = inputStream.readLine()) != null) {
AESDecrypt(msg);
}
}

key 和 iv 除了 key 中的最后一个字节外没有变化。如果我正在加密,我会得到一个随机的 base64 字符并将最后一个字节更改为该字符。如果它被解密,我从消息中获取最后一个字节并将 key 的最后一个值设置为它用于解密。

在 c++ 示例中,有一条未加密的消息和两条加密的消息。我可以很好地处理这些问题。

这就是问题所在,当我将消息发送到“加密”的远程服务器时,应用程序会等待响应,直到连接超时但从未收到响应。如果我发送未加密的消息,我会收到 7 个我可以成功解密的响应,最后

 org.bouncycastle.util.encoders.DecoderException: unable to decode base64 string: 
String index out of range: -4 at org.bouncycastle.util.encoders.Base64.decode(Unknown Source)

或者我在错误之前的最后一行将如下所示:

 ?"??n?i???el????s???!_S=??ah????CR??l6??]?{?l??Y?????Gn???+?????9!'??gU&4>??{X????G?.$c=??0?5??GP???_Q5????8??Z\?~???<Kr?????[2\ ???a$?C??z%?W???{?.?????eR?j????~?B"$??"z??W;???<?Yu??Y*???Z?K?e!?????f?;O(?Zw0B??g<???????????,)?L>???A"?????<?????W??@\???f%??j ?EhY/?? ?5R?34r???@?1??I??????M

如果我将加密/解密设置为使用 PKCS7Padding,当我的消息仍然加密时我没有收到任何响应,但是从服务器解密我得到 2 到 6 个响应,然后

 org.bouncycastle.crypto.InvalidCipherTextException: pad block corrupted

我对此一头雾水。我不知道我可能做错了什么所以我来到这里。希望so社区能指出我的错误,指导我正确的方向。

我有一点更新,我发现我的加密错误。我没有将随机 base64 值正确地放置在加密字符串的末尾,所以现在我这样做了。

encString += (char)randKey;

我现在可以从服务器得到响应。现在的问题是我有时会得到一两行可读的内容,但其余的都是垃圾。我问过运行服务器的人,他们在一些 c# 代码中说他们引用了

return UTF8Encoding.UTF8.GetString(resultArray);

这就是我要离开的全部。我已经尝试在我执行 getBytes 或新字符串的任何地方进行 UTF-8 编码,并且我已经尝试将 BurrferReader 流设为 UTF-8,但它仍然是垃圾。

最佳答案

你播种了 BCgit 了吗?这有 bouncycaSTLe 代码和示例。我在此存储库中使用的是 Csharp 版本。 https://github.com/bcgit/bc-java

所有加密原始示例都存储在这里:https://github.com/bcgit/bc-java/tree/master/core/src/test/java/org/bouncycastle/crypto/test

试试这个代码来测试 Aes-CBC

private void testNullCBC()
throws InvalidCipherTextException
{
BufferedBlockCipher b = new BufferedBlockCipher(new CBCBlockCipher(new AESEngine()));
KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917"));

b.init(true, new ParametersWithIV(kp, new byte[16]));

byte[] out = new byte[b.getOutputSize(tData.length)];

int len = b.processBytes(tData, 0, tData.length, out, 0);

len += b.doFinal(out, len);

if (!areEqual(outCBC1, out))
{
fail("no match on first nullCBC check");
}

b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f")));

len = b.processBytes(tData, 0, tData.length, out, 0);

len += b.doFinal(out, len);

if (!areEqual(outCBC2, out))
{
fail("no match on second nullCBC check");
}
}

关于java - BouncycaSTLe in Java奇数加密解密结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19008689/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com