我在Botan密码库中的c++ mc-eli看似实现上有问题。在整个互联网上,似乎只有一个例子,有一个链接到它。
但是这个例子已经有6年的历史了,因此它已经完全过时了,Botan文档没有提供任何其他的。
问题基本上是,不幸的是,函数名称和规范随着时间的推移发生了变化,因此在尝试使用它们时,我会遇到一些编译器错误。通过查看头实现,我成功地解开了其中的一些秘密。但现在我,坦率地说,在一堵墙前。
如果有人熟悉Botan的实现,可以给我一个提示,说明如何调用当前的函数,那就太好了。
这是我带记号的密码。我删除了许多不必要的代码和其他实现,以使其更具可读性。如果没有必要的模块,您也无法使它运行,但我将尝试以某种方式将其写下来,即拥有Botan库的人应该能够运行它。
//to compile: g++ -o mc_eliece mc_eliece.cpp -Wall -I/usr/local/include/botan-2/ -I/home/pi/projects/RNG_final/ -ltss2-esys -ltss2-rc -lbotan-2
#include <iostream>
#include <botan/rng.h>
#include <botan/system_rng.h>
#include <botan/mceies.h>
#include <botan/mceliece.h>
int main() {
Botan::size_t n = 1632; // Parameters for key generation
Botan::size_t t = 33;
// initialize RNG type
Botan::System_RNG rng; // is a standard Botan RNG
// create a new MCEliece private key with code length n and error weigth t
Botan::McEliece_PrivateKey sk1(rng, n, t); // actually works!
// derive the corresponding public key
Botan::McEliece_PublicKey pk1(*dynamic_cast<Botan::McEliece_PublicKey*>(&sk1)); // actually works!
// encode the public key
std::vector<uint8_t> pk_enc = pk1.subject_public_key(); // actually works!
// encode the private key
Botan::secure_vector<uint8_t> sk_enc = sk1.private_key_bits(); // had to replace sk1.pkcs8_private_key()
// encryption side: decode a serialized public key
Botan::McEliece_PublicKey pk(pk_enc);
McEliece_KEM_Encryptor enc(pk); // does not work, can't find a working corresponding function in the header
// perform encryption -> will find out if it works after upper case had been solved
std::pair<secure_vector<Botan::byte>,secure_vector<Botan::byte> > ciphertext__sym_key = enc.encrypt(rng);
secure_vector<Botan::byte> sym_key_encr = ciphertext__sym_key.second;
secure_vector<Botan::byte> ciphertext = ciphertext__sym_key.first;
// code used at the decrypting side: -> will find out if it works after upper case had been solved
// decode a serialized private key
McEliece_PrivateKey sk(sk_enc);
McEliece_KEM_Decryptor dec(sk);
// perform decryption -> will find out if it works after upper case had been solved
secure_vector<Botan::byte> sym_key_decr = dec.decrypt(&ciphertext[0],
ciphertext.size() );
// both sides now have the same 64-byte symmetric key.
// use this key to instantiate an authenticated encryption scheme.
// in case shorter keys are needed, they can simple be cut off.
return 0;
}请提前提供任何帮助。
发布于 2021-06-20 11:57:50
我现在已经更新了botan.pdf中的示例代码,以反映这些对Botan新的KEM的更改。
请注意,在公钥方案(如McEliece )的KEM上下文中使用KDF时,没有必要为KDF提供盐值。KDF可以在这里接受一个盐值,这仅仅是API的一个伪物,因为KDF也可以在其他上下文中使用。具体来说,只有在导出可能缺乏熵的秘密密钥(如密码)时,才需要盐分值。然后,它减少了基于预先计算的表的攻击。
发布于 2020-09-01 10:07:34
McEliece单元测试可以作为参考(链接)。
基于该代码,您的示例可以重写如下:
#include <botan/auto_rng.h>
#include <botan/data_src.h>
#include <botan/hex.h>
#include <botan/mceies.h>
#include <botan/mceliece.h>
#include <botan/pkcs8.h>
#include <botan/pubkey.h>
#include <botan/x509_key.h>
#include <cassert>
#include <iostream>
int main() {
// Parameters for McEliece key
// Reference: https://en.wikipedia.org/wiki/McEliece_cryptosystem#Key_sizes
Botan::size_t n = 1632;
Botan::size_t t = 33;
// Size of the symmetric key in bytes
Botan::size_t shared_key_size = 64;
// Key-derivation function to be used for key encapsulation
// Reference: https://botan.randombit.net/handbook/api_ref/kdf.html
std::string kdf{"KDF1(SHA-512)"};
// Salt to be used for key derivation
// NOTE: Pick salt dynamically, Botan recommds for example using a session ID.
std::vector<Botan::byte> salt{0x01, 0x02, 0x03};
Botan::AutoSeeded_RNG rng{};
// Generate private key
Botan::McEliece_PrivateKey priv{rng, n, t};
std::vector<Botan::byte> pub_enc{priv.subject_public_key()};
Botan::secure_vector<Botan::byte> priv_enc{Botan::PKCS8::BER_encode(priv)};
// Encrypting side: Create encapsulated symmetric key
std::unique_ptr<Botan::Public_Key> pub{Botan::X509::load_key(pub_enc)};
Botan::PK_KEM_Encryptor encryptor{*pub, rng, kdf};
Botan::secure_vector<Botan::byte> encapsulated_key{};
Botan::secure_vector<Botan::byte> shared_key1{};
encryptor.encrypt(encapsulated_key, shared_key1, shared_key_size, rng, salt);
std::cout << "Shared key 1: " << Botan::hex_encode(shared_key1) << std::endl;
// Decrypting side: Unpack encapsulated symmetric key
Botan::DataSource_Memory priv_enc_src{priv_enc};
std::unique_ptr<Botan::Private_Key> priv2{
Botan::PKCS8::load_key(priv_enc_src)};
Botan::PK_KEM_Decryptor decryptor{*priv2, rng, kdf};
Botan::secure_vector<Botan::byte> shared_key2{
decryptor.decrypt(encapsulated_key, shared_key_size, salt)};
std::cout << "Shared key 2: " << Botan::hex_encode(shared_key2) << std::endl;
assert(shared_key1 == shared_key2);
return 0;
}我用2.15.0测试了这段代码。示例输出:
$ g++ -g $(pkg-config --cflags --libs botan-2) test.cpp
$ ./a.out
Shared key 1: 32177925CE5F3D607BA45575195F13B9E0123BD739580DFCF9AE53D417C530DB115867E5E377735CB405CDA6DF7866C647F85FDAC5C407BB2E2C3A8E7D41A5CC
Shared key 2: 32177925CE5F3D607BA45575195F13B9E0123BD739580DFCF9AE53D417C530DB115867E5E377735CB405CDA6DF7866C647F85FDAC5C407BB2E2C3A8E7D41A5CC关于与您提供的代码相比,我更改了哪些内容的注释:
Botan::Private_Key也是一个Botan::Public_Key (参考文献)。因此,我们不需要将生成的私钥转换为公钥。相反,我们可以直接在私钥上调用subject_public_key来获取公钥编码。private_key_bits获取用于序列化工作的原始私钥位,但是使用PKCS8在互操作性方面可能更健壮。因此,出于这个原因,我会在私钥上使用Botan::PKCS8::BER_encode。McEliece_PublicKey不适用于我,因为构造器需要原始公钥位,而不是x509公钥编码。由于这个原因,我不得不使用Botan::X509::load_key。McEliece_KEM_Encryptor已被删除(参考文献):
为KEM (密钥封装)技术添加通用接口。转换McEliece KEM来使用它。先前的接口McEliece_KEM_Encryptor和McEliece_KEM_Decryptor已被删除。新的KEM接口现在使用一个KDF来散列结果键;要获得与McEliece_KEM_Encryptor先前提供的输出相同的结果,请使用"KDF1(SHA-512)“并精确地请求64个字节。相反,您可以使用Botan::PK_KEM_Encryptor,它将公钥作为参数,并从公钥推断要使用的加密算法。从代码中可以看出,通过这种方式它变得更加灵活,在生成密钥之后,我们不必引用McEliece。如果我们想要切换到不同的算法,我们只需要更改密钥生成部分,而不是密钥封装部分。
McEliece_KEM_Decryptor也是如此。https://stackoverflow.com/questions/63678081
复制相似问题