Java AES CBC解密第一块 我在java和C++之间的AES加密(CryptoPP是特定的)中遇到了一个大问题,我希望比我以前解决的加密密码更容易。p>

Java AES CBC解密第一块 我在java和C++之间的AES加密(CryptoPP是特定的)中遇到了一个大问题,我希望比我以前解决的加密密码更容易。p>,java,cryptography,aes,Java,Cryptography,Aes,当我解密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, -

当我解密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与块一起工作,所以我认为初始化向量可能有问题(因为只有第一个块被破坏),但正如你们所看到的,我以我认为合适的方式设置向量

我不知道为什么会这样。我会非常感激你的帮助,因为我没时间了

[编辑] 我添加了密码初始化。正如您所写的,它是AES/CBC/pkcs5p

在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());
CryptoPP::CBC_模式::加密m_加密;
CryptoPP::CBC_模式::解密m_AES解密;
QByteArray AESAlgorithMCODE::encrypt(常量QByteArray&plain)
{
std::字符串加密;
试一试{
StringSource(重新解释转换(plain.data()),plain.length(),true,
新的StreamTransformationFilter(m_),
新的字符串接收器(加密));
}catch(const CryptoPP::Exception&e){
抛出SymmetricAlgorithmException(例如what());
}
返回QByteArray(encrypted.c_str(),encrypted.length());
}

QByteArray AESAlgorithmCBCMode::解密(const QByteArray&加密)
{
std::字符串普通;
试一试{
StringSource(reinterpret_cast(encrypted.data())、encrypted.length()、true、,
新的StreamTransformationFilter(m_),
新(平原);;
}catch(const CryptoPP::Exception&e){
抛出SymmetricAlgorithmException(例如what());
}
返回QByteArray(plain.c_str(),plain.length());
}

键和初始化向量完全相同(我选中)。
有趣的是,这是一个更大的通信协议的一部分,之前的消息被加密和解密得非常好。开头也有零。

问题中给出了答案;即使有人明确表示应该将其作为答案发布,这一点也没有改变

答案是这样的:

关键是每次调用
doFinal()
时,它都会重置密码的状态。您应该做的是存储最后一个消息块(为Decryptor加密,为Encryptor解密),该消息块将在下次用作新的InitializationVector。然后,应使用此新IV调用
init()。当然,应该提供用于加密和解密的不同密码实例


我认为你也应该在帖子中添加:1。如何安装密码,例如cipher.getInstance(“AES/CBC/PKCS5Padding”)2。C++版本的代码。在预期结果中,前30个看起来非常可疑,前16个字节最终被损坏,可能使用不正确的初始化向量。确保它们匹配。我还想指出的是,在加密消息时,您应该始终生成一个随机IV–使用静态IV泄漏有关明文的信息,就像ECB模式一样。是的,我知道,每个消息的向量都应该更改,但我一发现这个问题就会这样做。两边的向量是完全相同的-我检查了几次。有没有一种方法(可能是一些在线加密机/解密机)可以测试哪一方是正确的?因为我没有找到一个可以使用字节而不是字符串的问题。这个问题显示为一个有很多向上投票但没有解决方案的问题。你能把问题的最后一部分改成答案,这样它就被标记为已解决了吗?大约两天后,你可以接受自己的答案。
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());