Crypto++中使用AES的示例

70

我一直在网上搜索能够教授加密技术和库的基础知识,并提供良好的c++ AES代码示例/教程,但是至今没有找到令人满意的材料。

要求良好: 简单易懂(只讲解适合快速学习的基础知识)。


你想了解如何使用库还是算法的基础? - Matteo Italia
@MatteoItalia 我的项目需要使用AES,所以学习该库是必须的(因为项目截止日期),但如果我能在学习过程中掌握一些知识,那就太好了! - yohannist
1
http://www.cryptopp.com/wiki/Advanced_Encryption_Standard - Behrouz.M
4
很遗憾,这个问题已经被关闭了! - user11914177
1个回答

99

官方文档 Crypto++ AES 是一个不错的起点。我从自己的存档中找到了一个基本的AES实现,如下:

请参考这里获取更多解释,建议您先理解算法,然后逐行理解每一步。

#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, 196-bit or 256-   
    //bit). This key is secretly exchanged between two parties before communication   
    //begins. DEFAULT_KEYLENGTH= 16 bytes
    CryptoPP::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() );
    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<CryptoPP::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;
}

安装细节:

sudo apt-get install libcrypto++-dev libcrypto++-doc libcrypto++-utils


2
我在附加依赖项中添加了cryptlib.lib并尝试在VS2010上构建它,但出现了47个链接错误,其中大多数如下所示:- error LNK2005: _tolower已在MSVCRTD.lib(MSVCR100D.dll)中定义,有什么帮助吗? - yohannist
1
我不知道键(key)在哪里被初始化了,我应该如何使用未知大小的std :: string类型进行初始化? - Shohreh
1
@AMomchilov,原因是当输入的字节数组使用代码plaintext.length() + 1时,最后一个0x0被添加到编码器的输入字节数组中。我只看到明文的大小为55,但解密文本的大小为56。我认为我们应该使用plaintext.length()而不是plaintext.length() +1 - ollydbg23
1
这对我大部分是有效的,但我发现decryptedtext字符串比plaintext多一个字节,因为它有一个额外的尾随空字节。我还不得不修复 byte类型的缺少命名空间,正如 @Micka 指出的那样。我使用这些修复更新了答案。 - Arthur Tacca
1
@Shohreh,虽然有点晚了,但他在memset命令中初始化了关键字。 - Roy2511
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接