高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。

默认密钥长度

AES 可使用16,24,或32字节密钥(分别对应128,192和256位)。 Crypto++ 库缺省的密钥长度是16字节,也就是 AES:: DEFAULT_KEYLENGTH

块大小

块大小被 AES::BLOCKSIZE 宏决定,对于 AES 加密,它始终是16字节。

Reference to block cipher object

You can also create a mode object that holds a reference to a block cipher object rather than an instance of it:

AES::Encryption aesEncryption(key, AES::DEFAULT_KEYLENGTH);
CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv);

ECB和CBC模式

对于 ECB 和 CBC 模式,你处理的数据必须是块大小的倍数。或者,你可以用 StreamTransformationFilter 围绕这个模式对象,并把它作为一个过滤器对象。StreamTransformationFilter 能够缓存数据到块中并根据需要填充。

下面这段代码输出AES的最小,最大和默认密钥长度。

cout << "key length: " << AES::DEFAULT_KEYLENGTH << endl;
cout << "key length (min): " << AES::MIN_KEYLENGTH << endl;
cout << "key length (max): " << AES::MAX_KEYLENGTH << endl;
cout << "block size: " << AES::BLOCKSIZE << endl;

输入结果如下,注意默认的密钥大小是16字节(128位)。

key length: 16
key length (min): 16
key length (max): 32
block size: 16

下面这段代码演示如何使用CBC模式加密和解密

#include <iostream>
#include <iomanip>

#include "modes.h"
#include "aes.h"
#include "filters.h"

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

    //Key and IV setup
    //AES encryption uses a secret key of a variable length (128-bit, 192-bit or 256-   
    //bit). This key is secretly exchanged between two parties before communication   
    //begins. DEFAULT_KEYLENGTH= 16 bytes
    byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ];
    memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH );
    memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE );

    //
    // String and Sink setup
    //
    std::string plaintext = "Now is the time for all good men to come to the aide...";
    std::string ciphertext;
    std::string decryptedtext;

    //
    // Dump Plain Text
    //
    std::cout << "Plain Text (" << plaintext.size() << " bytes)" << std::endl;
    std::cout << plaintext;
    std::cout << std::endl << std::endl;

    //
    // Create Cipher Text
    //
    CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, iv );

    CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( ciphertext ) );
    stfEncryptor.Put( reinterpret_cast<const unsigned char*>( plaintext.c_str() ), plaintext.length() + 1 );
    stfEncryptor.MessageEnd();

    //
    // Dump Cipher Text
    //
    std::cout << "Cipher Text (" << ciphertext.size() << " bytes)" << std::endl;

    for( int i = 0; i < ciphertext.size(); i++ ) {

        std::cout << "0x" << std::hex << (0xFF & static_cast<byte>(ciphertext[i])) << " ";
    }

    std::cout << std::endl << std::endl;

    //
    // Decrypt
    //
    CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
    CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );

    CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedtext ) );
    stfDecryptor.Put( reinterpret_cast<const unsigned char*>( ciphertext.c_str() ), ciphertext.size() );
    stfDecryptor.MessageEnd();

    //
    // Dump Decrypted Text
    //
    std::cout << "Decrypted Text: " << std::endl;
    std::cout << decryptedtext;
    std::cout << std::endl << std::endl;

    return 0;
}

如果需要加密的不是字符串而是一段二进制数据,只需把代码中的 CryptoPP::StringSink 替换成 CryptoPP::ArraySink

使用AES实现加密和解密

下面的示例使用 CFB 模式并就地的加密和解密。由于该模式不是 ECB 或 CBC,所以数据的长度并不需要是 AES 的块大小的倍数。

#ifdef CRYPTOPP_DLL_ONLY
#include "dll.h"
#else
#include "modes.h"
#include "aes.h"
#include "filters.h"
#include "osrng.h"
#endif

AutoSeededRandomPool rnd;

// Generate a random key
SecByteBlock key(0x00, AES::DEFAULT_KEYLENGTH);
rnd.GenerateBlock( key, key.size() );

// Generate a random IV
byte iv[AES::BLOCKSIZE];
rnd.GenerateBlock(iv, AES::BLOCKSIZE);

char plainText[] = "Hello! How are you.";
int messageLen = (int)strlen(plainText) + 1;

//////////////////////////////////////////////////////////////////////////
// Encrypt

CFB_Mode<AES>::Encryption cfbEncryption(key, key.size(), iv);
cfbEncryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen);

//////////////////////////////////////////////////////////////////////////
// Decrypt

CFB_Mode<AES>::Decryption cfbDecryption(key, key.size(), iv);
cfbDecryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen);

使用AES加密字符串

byte key[AES::DEFAULT_KEYLENGTH], iv[AES::BLOCKSIZE];
string plainText;

// ... populate key, iv, plainText here

string cipher;
StringSink* sink = new StringSink(cipher);
Base64Encoder* base64_enc = new Base64Encoder(sink);
CBC_Mode<AES>::Encryption aes(key, sizeof(key), iv);
StreamTransformationFilter* aes_enc = new StreamTransformationFilter(aes, base64_enc);
StringSource source(plainText, true, aes_enc);

参考链接:
Advanced Encryption Standard
Example of AES using Crypto++

相关文章:
Windows下使用MinGW编译Crypto++ 5.6.2
Qt pro文件中引用第三方库

标签: Crypto++, CryptoPP, AES加密, Crypto++ AES加密, Cryptopp 加密

已有 2 条评论

  1. […] 使用Crypto++库实现AES加密 […]

  2. […] 使用Crypto++库实现AES加密 […]

添加新评论