Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TOTP 2FA authentication support #4431

Open
ywarnier opened this issue Oct 23, 2022 · 1 comment
Open

Add TOTP 2FA authentication support #4431

ywarnier opened this issue Oct 23, 2022 · 1 comment

Comments

@ywarnier
Copy link
Member

ywarnier commented Oct 23, 2022

Chamilo (until now) does not support 2FA, which is increasingly asked for by large organizations. We want to have some kind of 2FA, and TOTP (Timebased One Time Password) seems to be something we'd like to use.

We can enable 2FA using TOTP (probably the easiest and most commonly used protocol for that) using https://github.com/Spomky-Labs/otphp/blob/v10.0/doc/index.md (v10 is the last one supporting PHP < 8.1).
Maybe PHPGangsta_GoogleAuthenticator would also serve the purpose, albeit focused on the GoogleAuthenticator rather than the protocol.

The implementation requires a secret key, which should be stored in the user table, along with the following other fields:

    mfa_enabled BOOLEAN NOT NULL DEFAULT false,
    mfa_service VARCHAR(255) NOT NULL,
    mfa_secret VARCHAR(255) NULL,
    mfa_backup_codes TEXT NULL,
    mfa_last_used TIMESTAMP NULL

Allow the feature to be "optional" or "enforced". If optional, users can simply enable the feature in a separate page on their profile page (the password edition page!).

If enforced, users will be asked to set-up their 2FA key at their next login, before they can access Chamilo.

The mfa_secret and the backup_codes should be encrypted at rest in the database, meaning we need to store those values in a reversible encryption.

This is one suggestion of little functions we could use for that (if openssl is available):

// Define encryption and decryption functions
function encryptTOTPSecret($plainText, $encryptionKey) {
    $iv = random_bytes(16); // Generate a secure IV
    $cipher = 'AES-256-CBC';
    $cipherText = openssl_encrypt($plainText, $cipher, $encryptionKey, 0, $iv);
    return base64_encode($iv . $cipherText);
}

function decryptTOTPSecret($encryptedText, $encryptionKey) {
    $data = base64_decode($encryptedText);
    $iv = substr($data, 0, 16);
    $cipherText = substr($data, 16);
    $cipher = 'AES-256-CBC';
    return openssl_decrypt($cipherText, $cipher, $encryptionKey, 0, $iv);
}

// Encryption key (stored securely somewhere)
$encryptionKey = 'your_secure_encryption_key_here';

// Encrypt the TOTP secret key before storing it in the database
$totpSecret = 'your_totp_secret_here';
$encryptedTOTPSecret = encryptTOTPSecret($totpSecret, $encryptionKey);

// Store $encryptedTOTPSecret in the database

// Decrypt the TOTP secret key after retrieving it from the database
$retrievedEncryptedTOTPSecret = 'encrypted_totp_secret_from_db';
$decryptedTOTPSecret = decryptTOTPSecret($retrievedEncryptedTOTPSecret, $encryptionKey);

We will then need some place to add the definition of one or various 2FA methods. This could be done in a JSON array in the settings table, and the mfa_service field would point the user to one specific 2FA service (defined in the JSON array).

@ywarnier ywarnier added this to the 2.0 milestone Oct 23, 2022
@christianbeeznest christianbeeznest self-assigned this Sep 26, 2024
christianbeeznest added a commit to christianbeeznest/chamilo-lms that referenced this issue Oct 2, 2024
@christianbeeznest
Copy link
Contributor

It is added with this PR #5836

Thanks for confirmation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants