使用Botan的ChaCha20Poly1305时如何检索MAC?

时间:2019-02-08 20:17:15

标签: c++ encryption botan

我正在使用Botan生成ChaCha20Poly1305的测试向量。 Botan有关AEAD密码的文档位于Cipher Modes | AEAD。它没有AEAD的示例,并且在检索Mac时遇到了麻烦。

下面的测试程序导致错误:

$ g++ -I build/include/ -I build/include/botan test.cxx ./libbotan-2.a -o test.exe
...

test.cxx: In function ‘void main(int argc, char* argv[])’:
test.cxx:35:42: error: conversion from ‘void’ to non-scalar type ‘Botan::secure_vector<unsigned char>’ {aka ‘std::vector<unsigned char, Botan::secure_allocator<unsigned char> >’} requested
  secure_vector<uint8_t> mac = enc->finish(cipher);
                               ~~~~~~~~~~~^~~~~~~~

我找到了AEAD_Mode的文档,但看不到如何检索Mac。使用mac = enc->finishmac = enc->final遵循他们的MAC示例,但这显然是错误的。

如何从密码中检索mac?

谢谢。


#include "rng.h"
#include "auto_rng.h"
#include "aead.h"
#include "hex.h"
#include <iostream>
#include <memory>

const size_t plainLen=8, size_t aadLen=8;

void main(int argc, char* argv[])
{
    using namespace Botan;
    AutoSeeded_RNG rng;

    std::unique_ptr<AEAD_Mode> enc =  AEAD_Mode::create("ChaCha20Poly1305", ENCRYPTION);

    const secure_vector<uint8_t> key = rng.random_vec(enc->maximum_keylength());
    const secure_vector<uint8_t> iv = rng.random_vec(enc->default_nonce_length());

    secure_vector<uint8_t> plain = rng.random_vec(plainLen);
    secure_vector<uint8_t> aad = rng.random_vec(aadLen);
    secure_vector<uint8_t> cipher(plain);

    enc->set_key(key);
    enc->set_ad(aad);
    enc->start(iv);

    secure_vector<uint8_t> mac = enc->finish(cipher);

    std::cout << "Key: " << hex_encode(key) << std::endl;
    std::cout << "IV: " << hex_encode(iv) << std::endl;
    std::cout << "AAD: " << hex_encode(aad) << std::endl;
    std::cout << "Plaintext: " << hex_encode(plain) << std::endl;
    std::cout << "Ciphertext: " << hex_encode(cipher) << std::endl;
    std::cout << "MAC: " << hex_encode(mac) << std::endl;
}

1 个答案:

答案 0 :(得分:0)

好像mac已附加到密文中。要提取Mac,只需截取密文的最后16个字节:

std::unique_ptr<AEAD_Mode> enc = AEAD_Mode::create("ChaCha20Poly1305", ENCRYPTION);

const secure_vector<uint8_t> key = rng.random_vec(enc->maximum_keylength());
const secure_vector<uint8_t> iv = rng.random_vec(enc->default_nonce_length());

secure_vector<uint8_t> plain = rng.random_vec(plainLen);
secure_vector<uint8_t> aad = rng.random_vec(aadLen);
secure_vector<uint8_t> cipher(plain);

enc->set_key(key);
enc->set_ad(aad);
enc->start(iv);

enc->finish(cipher);

secure_vector<uint8_t>::iterator where = cipher.end()-enc->tag_size();
secure_vector<uint8_t> mac(where, cipher.end());
cipher.erase(where, cipher.end());