如何在多次应用于输入的crypto++中实现AES?哪种AES模式?

问题描述

对于我的目标应用程序,我想针对给定的输入连续多次使用 AES。 连续加密 $i$ 次后,如果向后解密 $i$ 次,它应该会产生相同的起始输入。

举一些例子 code 我已经实施了一些可行的解决方案:

//g++ -o aestest aestest.cpp -lcryptopp    
#include <iostream>
#include <iomanip>

#include "cryptopp/modes.h"
#include "cryptopp/aes.h"
#include "cryptopp/filters.h"
#include <cassert>

void dispBA(std::vector<byte> &bav,std::string text =""){
    std::cout << text << " : size "<< bav.size() <<" byte"<< std::endl;
    for( long unsigned int i = 0; i < bav.size(); i++ ) {
         std::cout << std::dec<< (int)((static_cast<byte>(bav[i]))) << ",";
    }
    std::cout << std::endl << std::endl;
}

void encryptBV(CryptoPP::CBC_Mode_ExternalCipher::Encryption &cbcEncryption,std::vector<byte> &bytesIn,std::vector<byte> &bytesCrypOut,bool disp=false){
    CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption,new CryptoPP::ArraySink( &bytesCrypOut[0],bytesCrypOut.size()  ),CryptoPP::StreamTransformationFilter::NO_PADDING );
    stfEncryptor.Put(  &bytesIn[0],bytesIn.size() );
    stfEncryptor.MessageEnd();
    if(disp)dispBA(bytesCrypOut,"Cipher numbers");
}

void decryptBV(CryptoPP::CBC_Mode_ExternalCipher::Decryption &cbcDecryption,std::vector<byte> &bytesCrypIn,std::vector<byte> &bytesDecrOut,bool disp=false){
    CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption,new CryptoPP::ArraySink( &bytesDecrOut[0],bytesDecrOut.size()  ),CryptoPP::StreamTransformationFilter::NO_PADDING  );
    stfDecryptor.Put( &bytesCrypIn[0],bytesCrypIn.size() );
    stfDecryptor.MessageEnd();
    if(disp)dispBA(bytesDecrOut,"Decrypted numbers");
}


int main(int argc,char* argv[]) {

    //Key 32 bytes -> aes256
    //block size always 16
    const int myKeysize = 32;
    byte key[ myKeysize ],iv[ CryptoPP::AES::BLOCKSIZE ];
    memset( key,0x00,myKeysize ); // no key set yet
    memset( iv,CryptoPP::AES::BLOCKSIZE );
    
    //encryption
    std::vector<byte> bytesCryp(myKeysize);
    CryptoPP::AES::Encryption aesEncryption(key,myKeysize);
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption,iv );
    
    //decryption
    std::vector<byte> bytesDecr(myKeysize);   
    CryptoPP::AES::Decryption aesDecryption(key,myKeysize);
    CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption,iv );
        
    std::vector<byte> bytesIn = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
    assert(bytesIn.size()== myKeysize); 
    dispBA(bytesIn,"Starting number");
    
    //-----does work for single en/decryption
    // Create Cipher numbers    
    //encryptBV(cbcEncryption,bytesIn,bytesCryp,true);    
    // Decrypt
    //decryptBV(cbcDecryption,bytesDecr,true);
    
    int count = 42;
    for(int i=0; i < count; i++){       
        cbcEncryption.SetKeyWithIV(key,myKeysize,iv ); // ++
        encryptBV(cbcEncryption,bytesCryp); 
        cbcEncryption.SetKeyWithIV(key,bytesIn);
    }
    for(int i=0; i<count; i++){ 
        cbcDecryption.SetKeyWithIV(key,iv ); // ++
        decryptBV(cbcDecryption,bytesCryp);   
        cbcDecryption.SetKeyWithIV(key,bytesIn);
    }
    dispBA(bytesIn,"end"); // this does only return the correct value if lines marked with ++ are added
    
    //-----but it does also work if I repeat them without changing the inputs--- ["W2"]
    // Create Cipher numbers    
    //encryptBV(cbcEncryption,true);    
    //encryptBV(cbcEncryption,true);   
    // Decrypt
    //decryptBV(cbcDecryption,true);
    //decryptBV(cbcDecryption,true);


    return 0;
}

但是,目前这仅在我在每条消息(或生成新的 ExternalCipher)之后重置密钥时才有效。我虽然密钥只在单个(128,196,256 位)消息(或在一个长消息中)的轮次中改变,而不是通过消息继续。

有没有更好的方法来做到这一点?或者为什么会发生这种情况,如果我不更改输入,则不会发生这种情况(请参阅 ["W2"])?

Here 我发现了不同的操作模式。我猜这些是 AES 的不同实现。我应该使用某个吗? (编辑:欧洲央行?不支持 afaik)

解决方法

crypto++ Modes of Operation 中没有列出 ECB 模式,但是! crypto++ 显示了一些here,我可以做一些小的重写:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <CustomAction
        Title="Start"
        Location="ClientSideExtension.ApplicationCustomizer"
        ClientSideComponentId="a7074bac-2326-4ba6-8061-4931c05f47f0"
        ClientSideComponentProperties="{&quot;cssurl&quot;:&quot;/Style%20Library/custom.css&quot;}">
    </CustomAction>
</Elements>

它的运行速度也更快(约 60%)。

警告:这对于正常的 AES 使用是不安全的。

(如果其他人找到了更好的方法,我可以更改正确答案)