我在Java和C ++之间存在一个很大的问题(CryptoPP是特定的),我期望比不对称加密更容易,我之前设法解决了。
当我解密48个字节并且结果是38字节的byte []数组(size + code + hashOfCode)时,最后22个字节被正确解密而前16个字节是错误的。
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
byte[] key = { 107, -39, 87, -65, -1, -28, -85, -94, 105, 76, -94,
110, 48, 116, -115, 86 };
byte[] vector = { -94, 112, -23, 93, -112, -58, 18, 78, 1, 69, -92,
102, 33, -96, -94, 59 };
SecretKey aesKey = new SecretKeySpec(key, "AES");
byte[] message = { 32, -26, -72, 25, 63, 114, -58, -5, 4, 90, 54,
88, -28, 3, -72, 25, -54, -60, 17, -53, -27, -91, 34, -101,
-93, -3, -47, 47, -12, -35, -118, -122, -77, -7, -9, -123,
7, -66, 10, -93, -29, 4, -60, -102, 16, -57, -118, 94 };
IvParameterSpec aesVector = new IvParameterSpec(vector);
cipher.init(Cipher.DECRYPT_MODE, aesKey, aesVector);
byte[] wynik = cipher.doFinal(message);
Log.d("Solution here", "Solution");
for (byte i : wynik)
Log.d("Solution", "" + i);
} catch (Exception e) {
Log.d("ERROR", "TU");
e.printStackTrace();
}
我希望得到的解密信息是:
0 0 0 32 10 0 16 43 81 -71 118 90 86 -93 -24 -103 -9 -49 14 -29 -114 82 81 -7 -59 3 -77 87 -77 48 -92 -111 -125 -21 123 21 86 4
但我得到的是
28 127 -111 92 -75 26 18 103 79 13 -51 -60 -60 -44 18 126 -9 49 14 -29 -114 82 81 -7 -59 3 -77 87 -77 48 -92 -111 -125 -21 123 21 86 4
正如您所看到的,只有最后22个字节是相同的。
我知道AES可以使用块,因此我认为初始化向量可能是错误的(因为只有第一个块被破坏),但正如你所看到的那样我设置向量的方式我觉得没问题
我不知道为什么它会这样运作。任何帮助都会非常感激,因为我已经没时间了。
[编辑] 我添加了Cipher初始化。正如您所写,它是AES / CBC / PKCS5Padding。
在CryptoPP / C ++方面(实际上不是我的代码,所以我提供了我认为最有用的信息):
CryptoPP::CBC_Mode< CryptoPP::AES>::Encryption m_aesEncryption;
CryptoPP::CBC_Mode< CryptoPP::AES>::Decryption m_aesDecryption;
QByteArray AESAlgorithmCBCMode::encrypt(const QByteArray& plain)
{
std::string encrypted;
try {
StringSource(reinterpret_cast<const byte*>(plain.data()), plain.length(), true,
new StreamTransformationFilter(m_aesEncryption,
new StringSink(encrypted)));
} catch (const CryptoPP::Exception& e) {
throw SymmetricAlgorithmException(e.what());
}
return QByteArray(encrypted.c_str(), encrypted.length());
}
QByteArray AESAlgorithmCBCMode::decrypt(const QByteArray& encrypted)
{
std::string plain;
try {
StringSource(reinterpret_cast<const byte*>(encrypted.data()), encrypted.length(), true,
new StreamTransformationFilter(m_aesDecryption,
new StringSink(plain)));
} catch (const CryptoPP::Exception& e) {
throw SymmetricAlgorithmException(e.what());
}
return QByteArray(plain.c_str(), plain.length());
}
键和初始化向量完全相同(我检查过)。 有趣的部分是更大的通信协议的一部分,并且之前的消息被加密和解密完全正常。并且在开始时也有零。
答案 0 :(得分:0)
问题中提供了答案;即使在明确表示应将其作为答案发布后,这一点也没有改变。
这是答案:
关键是每次调用
doFinal()
时,它都会重置密码的状态。您应该做的是存储最后一条消息(为Decryptor加密并为Encryptor解密),该消息将在下次用作新的InitializationVector时使用。然后应该调用带有这个新IV的init()
。当然,应该提供用于加密和解密的密码的不同实例。