Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
database::security::encryption_manager Class Reference

Data encryption and key management. More...

#include <secure_connection.h>

Collaboration diagram for database::security::encryption_manager:
Collaboration graph

Public Member Functions

 encryption_manager ()=default
 Default constructor - used by database_context.
 
std::string encrypt_field_data (const std::string &data, const std::string &field_name) const
 
std::string decrypt_field_data (const std::string &encrypted_data, const std::string &field_name) const
 
bool generate_field_key (const std::string &field_name)
 
bool rotate_field_key (const std::string &field_name)
 
void set_master_encryption_key (const std::string &key)
 
bool configure_encrypted_column (const std::string &table, const std::string &column, encryption_type type)
 
bool is_column_encrypted (const std::string &table, const std::string &column) const
 

Private Member Functions

std::string derive_key (const std::string &field_name) const
 

Private Attributes

std::mutex encryption_mutex_
 
std::string master_key_
 
std::unordered_map< std::string, std::string > field_keys_
 
std::unordered_map< std::string, encryption_typeencrypted_columns_
 

Detailed Description

Data encryption and key management.

Note
This class uses dependency injection pattern. Access via database_context::get_encryption_manager() (Sprint 3, Task 3.3).

Example:

auto context = std::make_shared<database_context>();
auto enc_mgr = context->get_encryption_manager();

Definition at line 395 of file secure_connection.h.

Constructor & Destructor Documentation

◆ encryption_manager()

database::security::encryption_manager::encryption_manager ( )
default

Default constructor - used by database_context.

Member Function Documentation

◆ configure_encrypted_column()

bool database::security::encryption_manager::configure_encrypted_column ( const std::string & table,
const std::string & column,
encryption_type type )

Definition at line 642 of file secure_connection.cpp.

645 {
646 std::lock_guard<std::mutex> lock(encryption_mutex_);
647 std::string key = table + "." + column;
648 encrypted_columns_[key] = type;
649
650 // Auto-generate field key if not present
651 if (field_keys_.find(key) == field_keys_.end())
652 {
653 // Temporarily release lock to call generate_field_key
654 // Instead, inline the key generation
655 std::random_device rd;
656 std::mt19937 gen(rd());
657 std::uniform_int_distribution<> dis(0, 255);
658
659 std::string field_key(32, '\0');
660 for (auto& c : field_key)
661 {
662 c = static_cast<char>(dis(gen));
663 }
664
665 std::ostringstream oss;
666 for (unsigned char ch : field_key)
667 {
668 oss << std::hex << std::setfill('0') << std::setw(2)
669 << static_cast<int>(ch);
670 }
671 field_keys_[key] = oss.str();
672 }
673
674 return true;
675 }
std::unordered_map< std::string, std::string > field_keys_
std::unordered_map< std::string, encryption_type > encrypted_columns_

References encrypted_columns_, encryption_mutex_, and field_keys_.

◆ decrypt_field_data()

std::string database::security::encryption_manager::decrypt_field_data ( const std::string & encrypted_data,
const std::string & field_name ) const

Definition at line 499 of file secure_connection.cpp.

501 {
502 std::lock_guard<std::mutex> lock(encryption_mutex_);
503
504 if (encrypted_data.empty())
505 {
506 return {};
507 }
508
509 std::string key = derive_key(field_name);
510 if (key.empty())
511 {
512 return {};
513 }
514
515#ifdef DATABASE_HAS_OPENSSL
516 // AES-256-GCM decryption
517 if (encrypted_data.substr(0, 4) == "aes:")
518 {
519 key.resize(32, '\0');
520
521 auto first = encrypted_data.find(':', 4);
522 auto second = encrypted_data.find(':', first + 1);
523 if (first == std::string::npos || second == std::string::npos) return {};
524
525 auto iv = hex_to_bytes(encrypted_data.substr(4, first - 4));
526 auto ciphertext = hex_to_bytes(encrypted_data.substr(first + 1, second - first - 1));
527 auto tag = hex_to_bytes(encrypted_data.substr(second + 1));
528
529 EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
530 if (!ctx) return {};
531
532 std::vector<uint8_t> plaintext(ciphertext.size() + EVP_MAX_BLOCK_LENGTH);
533 int len = 0, pt_len = 0;
534
535 EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr);
536 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, static_cast<int>(iv.size()), nullptr);
537 EVP_DecryptInit_ex(ctx, nullptr, nullptr,
538 reinterpret_cast<const unsigned char*>(key.data()), iv.data());
539 EVP_DecryptUpdate(ctx, plaintext.data(), &len,
540 ciphertext.data(), static_cast<int>(ciphertext.size()));
541 pt_len = len;
542 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, static_cast<int>(tag.size()),
543 const_cast<uint8_t*>(tag.data()));
544
545 int ret = EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len);
546 EVP_CIPHER_CTX_free(ctx);
547
548 if (ret <= 0) return {};
549 pt_len += len;
550 return std::string(plaintext.begin(), plaintext.begin() + pt_len);
551 }
552#endif
553
554 // Legacy XOR format
555 std::string hex_data = encrypted_data;
556 if (hex_data.substr(0, 4) == "xor:")
557 {
558 hex_data = hex_data.substr(4);
559 }
560
561 std::string decoded;
562 decoded.reserve(hex_data.size() / 2);
563 for (size_t i = 0; i + 1 < hex_data.size(); i += 2)
564 {
565 unsigned int byte = 0;
566 std::istringstream iss(hex_data.substr(i, 2));
567 iss >> std::hex >> byte;
568 decoded.push_back(static_cast<char>(byte));
569 }
570
571 for (size_t i = 0; i < decoded.size(); ++i)
572 {
573 decoded[i] ^= key[i % key.size()];
574 }
575
576 return decoded;
577 }
std::string derive_key(const std::string &field_name) const

References derive_key(), and encryption_mutex_.

Here is the call graph for this function:

◆ derive_key()

std::string database::security::encryption_manager::derive_key ( const std::string & field_name) const
private

Definition at line 685 of file secure_connection.cpp.

686 {
687 // Check for field-specific key first
688 auto it = field_keys_.find(field_name);
689 if (it != field_keys_.end())
690 {
691 return it->second;
692 }
693
694 // Fall back to master key
695 if (!master_key_.empty())
696 {
697 return master_key_;
698 }
699
700 return {};
701 }

References field_keys_, and master_key_.

Referenced by decrypt_field_data(), and encrypt_field_data().

Here is the caller graph for this function:

◆ encrypt_field_data()

std::string database::security::encryption_manager::encrypt_field_data ( const std::string & data,
const std::string & field_name ) const

Definition at line 433 of file secure_connection.cpp.

435 {
436 std::lock_guard<std::mutex> lock(encryption_mutex_);
437
438 if (data.empty())
439 {
440 return {};
441 }
442
443 std::string key = derive_key(field_name);
444 if (key.empty())
445 {
446 return {};
447 }
448
449#ifdef DATABASE_HAS_OPENSSL
450 // AES-256-GCM field encryption with derived key
451 key.resize(32, '\0'); // Ensure 256-bit key
452
453 constexpr int iv_len = 12;
454 constexpr int tag_len = 16;
455
456 std::vector<uint8_t> iv(iv_len);
457 RAND_bytes(iv.data(), iv_len);
458
459 EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
460 if (!ctx) return {};
461
462 std::vector<uint8_t> ciphertext(data.size() + EVP_MAX_BLOCK_LENGTH);
463 std::vector<uint8_t> tag(tag_len);
464 int len = 0, ct_len = 0;
465
466 EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr);
467 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr);
468 EVP_EncryptInit_ex(ctx, nullptr, nullptr,
469 reinterpret_cast<const unsigned char*>(key.data()), iv.data());
470 EVP_EncryptUpdate(ctx, ciphertext.data(), &len,
471 reinterpret_cast<const unsigned char*>(data.data()),
472 static_cast<int>(data.size()));
473 ct_len = len;
474 EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len);
475 ct_len += len;
476 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, tag_len, tag.data());
477 EVP_CIPHER_CTX_free(ctx);
478
479 ciphertext.resize(ct_len);
480 return "aes:" + bytes_to_hex(iv) + ":" + bytes_to_hex(ciphertext) + ":" + bytes_to_hex(tag);
481#else
482 // XOR-based field encryption (placeholder)
483 std::string result = data;
484 for (size_t i = 0; i < result.size(); ++i)
485 {
486 result[i] ^= key[i % key.size()];
487 }
488
489 std::ostringstream oss;
490 for (unsigned char c : result)
491 {
492 oss << std::hex << std::setfill('0') << std::setw(2)
493 << static_cast<int>(c);
494 }
495 return "xor:" + oss.str();
496#endif
497 }

References derive_key(), and encryption_mutex_.

Here is the call graph for this function:

◆ generate_field_key()

bool database::security::encryption_manager::generate_field_key ( const std::string & field_name)

Definition at line 579 of file secure_connection.cpp.

580 {
581 std::lock_guard<std::mutex> lock(encryption_mutex_);
582
583 // Generate a random key for the field
584 std::random_device rd;
585 std::mt19937 gen(rd());
586 std::uniform_int_distribution<> dis(0, 255);
587
588 std::string key(32, '\0');
589 for (auto& c : key)
590 {
591 c = static_cast<char>(dis(gen));
592 }
593
594 // Hex-encode the key for storage
595 std::ostringstream oss;
596 for (unsigned char c : key)
597 {
598 oss << std::hex << std::setfill('0') << std::setw(2)
599 << static_cast<int>(c);
600 }
601 field_keys_[field_name] = oss.str();
602 return true;
603 }

References encryption_mutex_, and field_keys_.

◆ is_column_encrypted()

bool database::security::encryption_manager::is_column_encrypted ( const std::string & table,
const std::string & column ) const

Definition at line 677 of file secure_connection.cpp.

679 {
680 std::lock_guard<std::mutex> lock(encryption_mutex_);
681 std::string key = table + "." + column;
682 return encrypted_columns_.find(key) != encrypted_columns_.end();
683 }

References encrypted_columns_, and encryption_mutex_.

◆ rotate_field_key()

bool database::security::encryption_manager::rotate_field_key ( const std::string & field_name)

Definition at line 605 of file secure_connection.cpp.

606 {
607 std::lock_guard<std::mutex> lock(encryption_mutex_);
608
609 auto it = field_keys_.find(field_name);
610 if (it == field_keys_.end())
611 {
612 return false;
613 }
614
615 // Generate new key (in production, would re-encrypt existing data)
616 std::random_device rd;
617 std::mt19937 gen(rd());
618 std::uniform_int_distribution<> dis(0, 255);
619
620 std::string key(32, '\0');
621 for (auto& c : key)
622 {
623 c = static_cast<char>(dis(gen));
624 }
625
626 std::ostringstream oss;
627 for (unsigned char c : key)
628 {
629 oss << std::hex << std::setfill('0') << std::setw(2)
630 << static_cast<int>(c);
631 }
632 it->second = oss.str();
633 return true;
634 }

References encryption_mutex_, and field_keys_.

◆ set_master_encryption_key()

void database::security::encryption_manager::set_master_encryption_key ( const std::string & key)

Definition at line 636 of file secure_connection.cpp.

637 {
638 std::lock_guard<std::mutex> lock(encryption_mutex_);
639 master_key_ = key;
640 }

References encryption_mutex_, and master_key_.

Member Data Documentation

◆ encrypted_columns_

std::unordered_map<std::string, encryption_type> database::security::encryption_manager::encrypted_columns_
private

Definition at line 423 of file secure_connection.h.

Referenced by configure_encrypted_column(), and is_column_encrypted().

◆ encryption_mutex_

std::mutex database::security::encryption_manager::encryption_mutex_
mutableprivate

◆ field_keys_

std::unordered_map<std::string, std::string> database::security::encryption_manager::field_keys_
private

◆ master_key_

std::string database::security::encryption_manager::master_key_
private

Definition at line 421 of file secure_connection.h.

Referenced by derive_key(), and set_master_encryption_key().


The documentation for this class was generated from the following files: