将公共密钥存储在数据库(C )中
Storing public keys in database (C++)
我试图将公共密钥(PK)和签名(由加密 库生成)存储到SQLITE数据库中。我首先将密钥编码为:
pk[node].BEREncode(CryptoPP::StringSink(pkstring).Ref());
然后将它们存储在数据库中。但是,由于PK和签名具有特殊的特征,因此未正确存储在数据库中。我用于存储的是:
char * PK = (char*) malloc (BC.trans[l].PK.length()+1); //use malloc to manually manage the memory
std::strcpy(PK,BC.trans[l].PK.c_str());
char *zSQL = sqlite3_mprintf("INSERT INTO BC (PK VALUES ('%q');", PK);
rc = sqlite3_exec(db, zSQL, callback, (void*)data, &zErrMsg);// executes the command in sqlite and returns the status (whether stroing was successful or not.
free(PK);
应将字符串复制到字符中,并且问题在这里完全发生在将内容复制到字符中。我认为这是因为字符串具有特殊字符。因为哈希,我也有同样的跟进,但效果很好。仅用于PK和签名。我也使用了memcpy和strncpy。对此无济于事,但键仍未正确存储在数据库中。
有什么想法吗?
我已经更新了完整的代码。现在我可以存储PK,似乎很好,但是当我要求数据库删除一堆记录时,什么也不会发生。这意味着再次出现了问题。
这是代码:
int Network_Nodes =10;
int Block_Size=10;
int BC_lenght=0;
int Fin_BC_size =50;
std::vector<CryptoPP::RSA::PrivateKey> prk;
std::vector<CryptoPP::RSA::PublicKey> pk;
std::vector<std::string> prev_t;
struct Block {
std::string block_hash;
std::string block_num;
struct transactions {
std::string TransactionID;
std::string previousTransactionID;
std::string PK;
std::string Sign;
};
std::vector<transactions> trans;
} BC;
int generatekey()
{
for (int i=0;i<Network_Nodes;i++)
{
CryptoPP::AutoSeededRandomPool rng;
CryptoPP::InvertibleRSAFunction param;
param.GenerateRandomWithKeySize(rng,3072);
CryptoPP::RSA::PrivateKey privatekey(param);
CryptoPP::RSA::PublicKey publickey (param);
prk.push_back(privatekey);
pk.push_back(publickey);
}
return 0;
}
///////////////////////////////////////////////////////////////
void initialization()
{
for (int i=0;i<=Network_Nodes;i++)
{
prev_t.push_back("NULL");
}
//Creating database
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called";
/* Open database */
rc = sqlite3_open("RemovableBC.db", &db);
if( rc ) {
fprintf(stderr, "Can't open database: %sn", sqlite3_errmsg(db));
return;
} else {
// fprintf(stdout, "Opened database successfullyn");
}
sql = "DROP TABLE BC";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
/* Create a table in the data base to be used for storing data. Create SQL statement */
sql = "CREATE TABLE BC("
"T_ID TEXT ,"
"P_T_ID TEXT ,"
"PK BLOB ,"
"Signature BLOB ,"
"Block_ID TEXT );";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %sn", zErrMsg);
sqlite3_free(zErrMsg);
} else {
// fprintf(stdout, "Table created successfullyn");
}
sqlite3_close(db);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void fill_the_block(std::string block_content)
{
const char* data = "Callback function called";
SHA256 hash;
string digest;
sqlite3 *db=NULL;
char *sql;
char *zErrMsg = 0;
int rc;
char sqlStr[2000];
/* Open database */
rc = sqlite3_open("RemovableBC.db", &db);
if( rc ) {
fprintf(stderr, "Can't open database: %sn", sqlite3_errmsg(db));
return;
} else {
// fprintf(stdout, "Opened database successfullyn");
}
StringSource s(block_content, true, new HashFilter(hash, new HexEncoder(new StringSink(digest))));
BC.block_hash=digest;
for (int l=0 ; l<Block_Size ; l++)
{
char *begin = sqlStr;
char *end = begin + sizeof(sqlStr);
std::fill(begin, end, 0);
char *zSQL = sqlite3_mprintf("INSERT INTO BC ( T_ID , P_T_ID , PK , Signature , Block_ID ) VALUES ('%q','%q','%q','%q','%q');", BC.trans[l].TransactionID.c_str() ,BC.trans[l].previousTransactionID.c_str() ,BC.trans[l].PK.c_str() ,BC.trans[l].Sign.c_str(),BC.block_hash.c_str());
rc = sqlite3_exec(db, zSQL, callback, (void*)data, &zErrMsg);
sqlite3_free(zSQL);
if( rc != SQLITE_OK ) {
fprintf(stderr, "SQL error in populating : %sn", zErrMsg);
sqlite3_free(zErrMsg);
} else {
}
sqlite3_close(db); //We close the connection we have with the database
}
///////////////////////////////////////////////////////////////////////////
void populate_bc ()
{
int generated_blocks=0;
int stored_trans_in_block=0;
int node=0;
std::string block_content,trans_cont;
std::string pkstring;
std::string signature;
std::string mes ="This message is going to be singed";
while (BC_lenght <=Fin_BC_size )
{
if (generated_blocks <= 10){
if (node >= Network_Nodes)
{
node=0; //cout << "step 4" <<endl;
}
if (stored_trans_in_block >= Block_Size)
{
cout << "block size is "<< BC_lenght<<endl;
fill_the_block(block_content);
BC_lenght++;
block_content.clear();
stored_trans_in_block=0;
for(int o=0; o<stored_trans_in_block;o++)
{
BC.trans[o] = {};
}
BC.trans = {};
BC ={};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (prev_t[node]=="NULL")
{
// cout << "We are populating on behafe of "<< node<< endl;
trans_cont="";
BC.trans.push_back(Block::transactions());
BC.trans[stored_trans_in_block].previousTransactionID ="NULL";
// byte public_key[] = pk[node];
std::string endoced_pub;
Base64Encoder pubKeySink(new StringSink(endoced_pub));
pk[node].DEREncode(pubKeySink);
pk[node].BEREncode(CryptoPP::StringSink(pkstring).Ref());
BC.trans[stored_trans_in_block].PK=endoced_pub;
CryptoPP::AutoSeededRandomPool rng;
CryptoPP::RSASSA_PKCS1v15_SHA_Signer signer(prk[node]);
CryptoPP::StringSource ss1(mes, true,
new CryptoPP::SignerFilter(rng, signer,
new CryptoPP::StringSink(signature)
) // SignerFilter
); // StringSource
// cout << "step 1" <<endl;
BC.trans[stored_trans_in_block].Sign=signature;
trans_cont = "NULL" + pkstring + signature;
SHA256 hash;
string digest;
StringSource s(trans_cont, true, new HashFilter(hash, new HexEncoder(new StringSink(digest))));
// cout << "step 2" <<endl;
BC.trans[stored_trans_in_block].TransactionID=digest;
prev_t[node] =digest; // This keeps the previous transaction of each node in an array and thus we can later use to populate the BC
block_content+=digest; // This is to calculate the ID of the block which is the hash of all TIDs (hash of hash of all trnasctions)
node++;
stored_trans_in_block++;
// cout << "step 3" <<endl;
}//end of if (prev_t[node]=="NULL")
else
{// cout << "step 6" <<endl;
trans_cont="";
BC.trans.push_back(Block::transactions());
BC.trans[stored_trans_in_block].previousTransactionID =prev_t[node];
std::string endoced_pub;
Base64Encoder pubKeySink(new StringSink(endoced_pub));
pk[node].DEREncode(pubKeySink);
// pubKeySink.MessageEnd();
// pk[node].BEREncode(CryptoPP::StringSink(pkstring).Ref());
BC.trans[stored_trans_in_block].PK = endoced_pub;
// BC.trans[stored_trans_in_block].PK= pk[node];
CryptoPP::AutoSeededRandomPool rng;
CryptoPP::RSASSA_PKCS1v15_SHA_Signer signer(prk[node]);
CryptoPP::StringSource ss1(mes, true,
new CryptoPP::SignerFilter(rng, signer,
new CryptoPP::StringSink(signature)
) // SignerFilter
); // StringSource
BC.trans[stored_trans_in_block].Sign=signature;
trans_cont = prev_t[node] + pkstring + signature;
SHA256 hash;
string digest;
StringSource s(trans_cont, true, new HashFilter(hash, new HexEncoder(new StringSink(digest))));
BC.trans[stored_trans_in_block].TransactionID=digest;
prev_t[node] =digest;
block_content+=digest;
node++;
stored_trans_in_block++;
}
generated_blocks++;
}
else
{
generated_blocks=0;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////
void remove_node (int i)
{
std::string search_node; //This is the ID of the transaction that we need to search for in the BC,
sqlite3 *db;
std::string endoced_pub;
Base64Encoder pubKeySink(new StringSink(endoced_pub));
pk[i].DEREncode(pubKeySink);
// pubKeySink.MessageEnd();
char *sql;
int rc;
char *zErrMsg = 0;
const char* data = "Callback function called";
/* Open database */
rc = sqlite3_open("RemovableBC.db", &db);
if( rc ) {
fprintf(stderr, "Can't open database: %sn", sqlite3_errmsg(db));
return;
} else {
// fprintf(stderr, "Opened database successfullyn");
}
/* Execute SQL statement */
// char *zSQL = sqlite3_mprintf("DELETE from BC");
char * Search_NODE = (char*) malloc (endoced_pub.length()+1);
std::strcpy(Search_NODE,endoced_pub.c_str());
std::strcpy(Search_NODE,search_node.c_str());
// char *zSQL = sqlite3_mprintf("DELETE from BC where PK = '%q';", Search_NODE);
char *zSQL = sqlite3_mprintf("UPDATE BC set Signature = null and PK = null where PK = '%q';", endoced_pub.c_str());
rc = sqlite3_exec(db, zSQL, callback, (void*)data, &zErrMsg);
cout<< endoced_pub.c_str()<<endl;
if( rc != SQLITE_OK ) {
fprintf(stderr, "SQL error in removing a record: %sn", zErrMsg);
sqlite3_free(zErrMsg);
} else {
// fprintf(stdout, "Operation done successfullyn");
}
sqlite3_close(db);
free(Search_NODE);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main() {
auto initial = std::chrono::high_resolution_clock::now();
generatekey();
cout << "Keys are generated for " <<Network_Nodes << " nodes..." << endl;
clock_t begin_block_pup = clock();
initialization();
cout << "Initializing previous transaction vector..." << endl;
//clock_t ti =clock();
//double time = double (ti)/CLOCKS_PER_SEC;
clock_t ti2 =clock();
double time2 = double (ti2)/CLOCKS_PER_SEC;
//cout << "second time is " << done <<endl;
populate_bc();
cout << "BC has been populated with "<< BC_lenght <<" blocks..." << endl;
return 0;
}
系统的问题是,您需要将PK数据存储为blob或将其编码为7位ASCII。
sqlite具有一些国际化支持,可以将存储为字符串的原始二进制数据转换为其他形式。(例如UTF-8转换)
因此,要么使用斑点,要么在这个问题的答案中,因此:sqlite blob,
或首先将字节转换为7位ASCII(例如B64编码),然后存储数据。
记住,您需要B64以后解码结果。
相关文章:
- SSH通过/sbin/SSH无法读取RSA密钥文件(从控制台运行)
- 允许从 std::map 的密钥窃取资源?
- TMap::Emplace() 在应用现有密钥时会覆盖吗?
- 在没有密钥的情况下读取密文的剩余噪声预算
- 如何修复无效的API密钥,IP或操作权限错误?
- 所有可能的链接生成器与64位密钥
- 如何在unordered_map中更改密钥?
- 获取当前密钥状态?
- curl_easy_perform() 失败:SSL 对等证书或 SSH 远程密钥不正常
- 将密钥发送到非前台的游戏窗口
- 有哪些方法可以对基于 256 位密钥的矩阵进行加扰?
- 如何在精灵表上的两个不同部分之间来回切换,同时用户仍使用 SFML 持有密钥
- 如何将CNG密钥转换为OpenSSL EVP_PKEY(反之亦然)?
- 运行密钥密码解密知道密钥?
- std::unordered_map 运算符 [] 是否对非现有密钥进行零初始化?
- 封装 std::map 以允许迭代,但没有直接密钥访问?
- 如果我使用同一个密钥推送用户数据两次,会发生什么
- 如何在C++中创建自己的编译密钥
- 重载std::映射不同的密钥类型
- 将公共密钥存储在数据库(C )中