将公共密钥存储在数据库(C )中

Storing public keys in database (C++)

本文关键字:数据库 密钥 存储      更新时间:2023-10-16

我试图将公共密钥(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以后解码结果。