Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Encryption 使用Crypto+;将IV和数据连接在Base64字符串中+;?_Encryption_Base64_Aes_Crypto++_Cbc Mode - Fatal编程技术网

Encryption 使用Crypto+;将IV和数据连接在Base64字符串中+;?

Encryption 使用Crypto+;将IV和数据连接在Base64字符串中+;?,encryption,base64,aes,crypto++,cbc-mode,Encryption,Base64,Aes,Crypto++,Cbc Mode,我需要将字符串加密到AES/CBC。为了以后能够取消加密,我必须将IV存储在最终结果中,该结果必须是base64字符串 我使用这个和Crypto++示例成功地做到了这一点: std::string String::AESEncryptString(std::string str, std::string key) { std::string encoded; std::string b64Result = ""; AutoSeededRandomPool prng;

我需要将字符串加密到AES/CBC。为了以后能够取消加密,我必须将IV存储在最终结果中,该结果必须是base64字符串

我使用这个和Crypto++示例成功地做到了这一点:

std::string String::AESEncryptString(std::string str, std::string key)
{
    std::string encoded;
    std::string b64Result = "";

    AutoSeededRandomPool prng;

    unsigned char iv[AES::BLOCKSIZE];
    prng.GenerateBlock(iv, sizeof(iv));

    StringSink output(encoded);

    // Put the IV at the begining of the output
    StringSource(iv, sizeof(iv), true,
        new Redirector(output)
    );

    try {
        CBC_Mode<AES>::Encryption encryptor((unsigned char *)key.c_str(), key.length(), iv);

        StringSource s(str, true, 
            new StreamTransformationFilter(encryptor, 
                new Redirector(output), StreamTransformationFilter::PKCS_PADDING
            )
        );

        // Convert to b64
        StringSource (encoded, true,
            new Base64Encoder(
                new StringSink(b64Result),
                false // do not append a newline
            )
        );

        return b64Result;
    } catch (const Exception& e) {
        return "";
    }
}
std::string string::aescencryptstring(std::string str,std::string key)
{
std::字符串编码;
std::字符串b64Result=“”;
自动进料器和OMPOOL prng;
无符号字符iv[AES::BLOCKSIZE];
prng.发电机锁(iv,尺寸(iv));
字符串接收器输出(编码);
//将IV置于输出的开头
StringSource(iv,sizeof(iv),真,
新重定向器(输出)
);
试一试{
CBC_模式::加密加密程序((unsigned char*)key.c_str(),key.length(),iv);
源字符串(str,true,
新的StreamTransformationFilter(加密机、,
新重定向器(输出),StreamTransformationFilter::PKCS_填充
)
);
//转换成b64
StringSource(已编码,真,
新型Base64编码器(
新StringSink(b64Result),
false//不追加换行符
)
);
返回结果;
}捕获(常量异常和e){
返回“”;
}
}
要解密base64字符串,我首先提取IV,然后解密其余数据:

std::string String::AESDecryptString(std::string str, std::string key)
{
    unsigned char iv[AES::BLOCKSIZE];

    std::string b64decoded;
    std::string decoded;

    try {
        StringSource(str, true,
            new Base64Decoder(
                new StringSink(b64decoded)
            )
        );

        StringSource ss(b64decoded, false);

        // Get the IV
        ArraySink ivSink(iv, sizeof(iv));
        ss.Attach(new Redirector(ivSink));
        ss.Pump(AES::BLOCKSIZE);


        CBC_Mode<AES>::Decryption decryptor((unsigned char *)key.c_str(), key.length(), iv);


        ByteQueue queue;
        ss.Detach(
            new StreamTransformationFilter(decryptor,
                new Redirector(queue)
            )
        );
        ss.PumpAll(); // Pump remainder bytes

        StringSink decodedSink(decoded);
        queue.TransferTo(decodedSink);
        return decoded;
    }
    catch (const Exception& e) {
        return "";
    }
}
std::string string::aesscryptstring(std::string str,std::string key)
{
无符号字符iv[AES::BLOCKSIZE];
std::字符串B64已解码;
std::字符串解码;
试一试{
StringSource(str,true,
新的Base64解码器(
新StringSink(B64解码)
)
);
StringSource ss(B64解码,假);
//静脉注射
ArraySink ivSink(iv,sizeof(iv));
ss.连接(新重定向器(ivSink));
不锈钢泵(AES::块尺寸);
CBC_模式::解密解密器((unsigned char*)key.c_str(),key.length(),iv);
字节队列;
分离(
新的StreamTransformationFilter(解密程序,
新重定向程序(队列)
)
);
ss.PumpAll();//泵送剩余字节
StringSink解码数据链路(已解码);
queue.TransferTo(decodedSink);
返回解码;
}
捕获(常量异常和e){
返回“”;
}
}
一切都很好,但由于我刚刚发现Crypto++和流水线范例,我觉得我可能已经完成了太多的步骤来实现我想要的


有更简洁或更有效的方法吗?

为链接创建锚类。跟随

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#ifndef CRYPTOPP\u无\u全局\u字节
命名空间CryptoPP{typedef无符号字符字节;}
#endif//CRYPTOPP\u NO\u全局\u字节
const std::string seckey=“this-has-16-char”;
类锚点:公共CryptoPP::无缓冲区
{
公众:
锚点(CryptoPP::BufferedTransformation*attachment=NULL){Detach(attachment);};
大小Put2(常量CryptoPP::byte*inString,大小长度,int messageEnd,bool阻塞)
{
return AttachedTransformation()->Put2(inString、length、messageEnd、blocking);
}
};
/**
*编码:返回编码
*
*/
布尔编码(常量std::字符串和输入,std::字符串和输出)
{
if(seckey.length()!=CryptoPP::AES::DEFAULT_KEYLENGTH)返回false;
无符号字符iv[CryptoPP::AES::BLOCKSIZE];
//CryptoPP::AutoSeedRandomPool prng;
//prng.发电机锁(iv,尺寸(iv));
memcpy(iv,“this-allow-has-16”,CryptoPP::AES::BLOCKSIZE);
output.clear();
试一试{
锚;
//将IV置于输出的开头
附加(新的CryptoPP::StringSink(输出));
抛锚。抛锚(四、四);
anchor.MessageEnd();
anchor.Detach();
CryptoPP::CBC_Mode::Encryption encryptor((unsigned char*)seckey.c_str(),seckey.length(),iv);
Attach(新的CryptoPP::StreamTransformationFilter(encryptor,NULL,CryptoPP::StreamTransformationFilter::PKCS_PADDING));
Attach(新的CryptoPP::Base64Encoder(NULL,false));
附加(新的CryptoPP::StringSink(输出));
anchor.Put((CryptoPP::byte*)input.c_str(),input.length());
anchor.MessageEnd();
}
catch(const CryptoPP::Exception&e){
返回false;
}
返回true;
}
/**
*解码:返回解码
*
*/
布尔解码(常量std::字符串和输入,std::字符串和输出)
{
if(seckey.length()!=CryptoPP::AES::DEFAULT_KEYLENGTH)返回false;

如果(input.length()您可以将这两个步骤合并为一个
StringSource
调用:

strings源代码(str,true,
新StreamTransformationFilter(
加密机,
新型Base64编码器(
新StringSink(b64Result),
false//不追加换行符
),
StreamTransformationFilter::PKCS\U填充
)
);
源字符串(
是的,
新的Base64解码器(
新StreamTransformationFilter(解密器、新StringSink(已解码))
)
);

我认为这是你能做的最好的了。如果你愿意,你可以将它包装在一个类中,但这只是在移动工作。例如,将它包装在一个类中,请参见
DefaultEncryptor
DefaultEncryptorWithMAC
类。这些类将种子材料放在数据的前面,然后派生一个密钥和IV from种子。(在派生过程中也会使用密码,但需要保留种子)。
#include <iostream>
#include <string>
#include <cstdlib>
#include <cryptopp/osrng.h>
#include <cryptopp/base64.h>
#include <cryptopp/aes.h>
#include <cryptopp/filters.h>
#include <cryptopp/modes.h>
#include <cryptopp/cryptlib.h>

#ifndef CRYPTOPP_NO_GLOBAL_BYTE
namespace CryptoPP { typedef unsigned char byte; }
#endif  // CRYPTOPP_NO_GLOBAL_BYTE

const std::string seckey = "this-has-16-char";

class Anchor : public CryptoPP::Bufferless<CryptoPP::Filter>
{
public:
    Anchor(CryptoPP::BufferedTransformation* attachment = NULL) { Detach(attachment); };
    size_t Put2(const CryptoPP::byte * inString, size_t length, int messageEnd, bool blocking )
    {
        return AttachedTransformation()->Put2(inString, length, messageEnd, blocking );
    }
};

/**
* Encode : return encoded
*
*/
bool Encode(const std::string& input, std::string& output)
{
    if (seckey.length()!=CryptoPP::AES::DEFAULT_KEYLENGTH) return false;
    unsigned char iv[CryptoPP::AES::BLOCKSIZE];
    // CryptoPP::AutoSeededRandomPool prng;
    // prng.GenerateBlock(iv, sizeof(iv));
    memcpy(iv, "this-also-has-16", CryptoPP::AES::BLOCKSIZE);
    output.clear();

    try {

        Anchor anchor;

        // Put the IV at the begining of the output
        anchor.Attach(new CryptoPP::StringSink(output));
        anchor.Put( iv, sizeof(iv) );
        anchor.MessageEnd();
        anchor.Detach();

        CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encryptor((unsigned char *)seckey.c_str(), seckey.length(), iv);
        anchor.Attach(new CryptoPP::StreamTransformationFilter(encryptor,NULL, CryptoPP::StreamTransformationFilter::PKCS_PADDING));
        anchor.Attach(new CryptoPP::Base64Encoder(NULL, false));
        anchor.Attach(new CryptoPP::StringSink(output));

        anchor.Put( (CryptoPP::byte*)input.c_str(), input.length() );
        anchor.MessageEnd();
    }
    catch (const CryptoPP::Exception& e) {
        return false;
    }
    return true;
}

/**
* Decode : return decoded
*
*/
bool Decode(const std::string& input, std::string& output)
{
    if (seckey.length()!=CryptoPP::AES::DEFAULT_KEYLENGTH) return false;
    if (input.length()<=CryptoPP::AES::BLOCKSIZE) return false; // no iv
    unsigned char iv[CryptoPP::AES::BLOCKSIZE];
    memcpy(iv, input.c_str(), CryptoPP::AES::BLOCKSIZE);

    try {
        // Convert from b64 and decode
        CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decryptor((unsigned char *)seckey.c_str(), seckey.length(), iv);

        Anchor anchor;
        anchor.Attach(new CryptoPP::Base64Decoder());
        anchor.Attach(new CryptoPP::StreamTransformationFilter( decryptor, NULL));
        anchor.Attach(new CryptoPP::StringSink(output));

        anchor.Put( (const CryptoPP::byte*)&input[CryptoPP::AES::BLOCKSIZE], input.length()-CryptoPP::AES::BLOCKSIZE );
        anchor.MessageEnd();

    }
    catch (const CryptoPP::Exception& e) {
        return false;
    }
    return true;
}

int main()
{

    std::string input = "The five boxing wizards jump quickly.";
    std::string output;
    bool status = Encode(input,output);
    if (status) std::cerr << "Encoded: " << output << std::endl;
    input.clear();
    status = Decode(output,input);
    if (status) std::cerr << "Decoded: " << input << std::endl;

}