diff --git a/encrypted_login.install b/encrypted_login.install
index 95dd9ea34e7b51fd882477ad0191172d6147a341..f63f4533f70f4fc24cec47a45bf2b3985e3ceef4 100644
--- a/encrypted_login.install
+++ b/encrypted_login.install
@@ -11,47 +11,68 @@ use Drupal\Core\Database\Database;
  * Implements hook_schema().
  */
 function encrypted_login_schema() {
-  $schema['encrypted_login_keys'] = [
-    'description' => 'Stores the AES encryption keys.',
-    'fields' => [
-      'key_id' => [
-        'type' => 'serial',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'description' => 'Primary key for the table.',
-      ],
-      'aes_key' => [
-        'type' => 'text',
-        'size' => 'big',
-        'not null' => TRUE,
-        'description' => 'The AES encryption key (Base64-encoded).',
-      ],
-      'created' => [
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Timestamp when the key was created.',
-      ],
-    ],
-    'primary key' => ['key_id'],
-  ];
-  return $schema;
+  // We no longer need the encrypted_login_keys table since AES keys
+  // are generated client-side and not stored in the database.
+  return [];
 }
 
 /**
  * Implements hook_install().
  */
 function encrypted_login_install() {
-  // Generate a random 256-bit AES key.
-  $key = random_bytes(32);
-
-  // Insert the key into the database.
-  \Drupal::database()->insert('encrypted_login_keys')
-    ->fields([
-      'aes_key' => base64_encode($key),
-      'created' => \Drupal::time()->getRequestTime(),
-    ])
-    ->execute();
-
-  \Drupal::logger('encrypted_login')->info('AES key generated and stored in the database.');
+  // Generate RSA Key Pair with stronger key length and proper padding.
+  $config = [
+    'private_key_bits' => 2048,
+    'private_key_type' => OPENSSL_KEYTYPE_RSA,
+    'digest_alg' => 'sha256',
+  ];
+
+  try {
+    // Generate new key pair.
+    $res = openssl_pkey_new($config);
+    if ($res === FALSE) {
+      throw new \Exception('Failed to generate RSA key pair: ' . openssl_error_string());
+    }
+
+    // Export private key.
+    if (!openssl_pkey_export($res, $private_key)) {
+      throw new \Exception('Failed to export private key: ' . openssl_error_string());
+    }
+
+    // Get public key.
+    $key_details = openssl_pkey_get_details($res);
+    if ($key_details === FALSE) {
+      throw new \Exception('Failed to get key details: ' . openssl_error_string());
+    }
+    $public_key = $key_details['key'];
+
+    // Store RSA keys securely in state API.
+    \Drupal::state()->set('encrypted_login.rsa_private_key', $private_key);
+    \Drupal::state()->set('encrypted_login.rsa_public_key', $public_key);
+
+    \Drupal::logger('encrypted_login')->info('RSA key pair successfully generated and stored.');
+  }
+  catch (\Exception $e) {
+    \Drupal::logger('encrypted_login')->error('Failed to initialize encrypted login: @message', ['@message' => $e->getMessage()]);
+    throw $e;
+  }
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function encrypted_login_uninstall() {
+  // Clean up state variables.
+  \Drupal::state()->delete('encrypted_login.rsa_private_key');
+  \Drupal::state()->delete('encrypted_login.rsa_public_key');
+}
+
+/**
+ * Remove encrypted_login_keys table and clean up old AES keys.
+ */
+function encrypted_login_update_8001() {
+  $schema = Database::getConnection()->schema();
+  if ($schema->tableExists('encrypted_login_keys')) {
+    $schema->dropTable('encrypted_login_keys');
+  }
 }
diff --git a/encrypted_login.libraries.yml b/encrypted_login.libraries.yml
index 43e53957b6eaea8263f5001b4ea15b2f56871bf0..d69e69456bc93ddb0272d974b00a7210c37ade89 100644
--- a/encrypted_login.libraries.yml
+++ b/encrypted_login.libraries.yml
@@ -3,5 +3,6 @@ encrypted_login:
   js:
     js/encrypted_login.js: {}
     https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js: {}
+    https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/2.3.1/jsencrypt.min.js: {}
   dependencies:
     - core/jquery
diff --git a/encrypted_login.module b/encrypted_login.module
index 75e21890f1ccc48418935b40f5f48464a0c93b32..033e8e621f99b12020a7d3113094a2562f5ca21d 100644
--- a/encrypted_login.module
+++ b/encrypted_login.module
@@ -13,6 +13,12 @@ use Drupal\Core\Form\FormStateInterface;
 function encrypted_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
   if ($form_id === 'user_login_form') {
     // Add hidden fields for encrypted credentials.
+    $form['encrypted_aes_key'] = [
+      '#type' => 'hidden',
+      '#default_value' => '',
+      '#attributes' => ['id' => 'edit-encrypted-aes-key'],
+    ];
+
     $form['encrypted_password'] = [
       '#type' => 'hidden',
       '#default_value' => '',
@@ -22,10 +28,10 @@ function encrypted_login_form_alter(&$form, FormStateInterface $form_state, $for
     // Attach the JavaScript library.
     $form['#attached']['library'][] = 'encrypted_login/encrypted_login';
 
-    // Add custom validation as the first validator
+    // Add custom validation as the first validator.
     array_unshift($form['#validate'], 'encrypted_login_validate_encrypted_credentials');
 
-    // Disable the default required validation for the original fields
+    // Disable the default required validation for the original fields.
     $form['pass']['#required'] = FALSE;
   }
 }
@@ -34,60 +40,47 @@ function encrypted_login_form_alter(&$form, FormStateInterface $form_state, $for
  * Custom validation handler for encrypted credentials.
  */
 function encrypted_login_validate_encrypted_credentials(array &$form, FormStateInterface $form_state) {
+  $encrypted_aes_key = $form_state->getValue('encrypted_aes_key');
   $encrypted_password = $form_state->getValue('encrypted_password');
 
+  $aes_key = '';
+  $private_key = \Drupal::state()->get('encrypted_login.rsa_private_key');
+
+  // Decrypt the AES key using RSA.
+  if (!openssl_private_decrypt(base64_decode($encrypted_aes_key), $aes_key, $private_key)) {
+    \Drupal::logger('encrypted_login')->error('RSA decryption of AES key failed.');
+    $form_state->setError($form, t('Authentication error. Please try again.'));
+    return;
+  }
+
+  // Convert the decrypted base64 AES key to raw binary.
+  $raw_aes_key = base64_decode($aes_key);
   if (empty($encrypted_password)) {
-    \Drupal::logger('encrypted_login')->error('Empty encrypted credentials received');
+    \Drupal::logger('encrypted_login')->error('Empty encrypted credentials received.');
     $form_state->setError($form, t('Login credentials are required.'));
     return;
   }
 
-  // Fetch the AES key from the database.
-  $aes_key = encrypted_login_get_aes_key();
-
-  if (!$aes_key) {
-    \Drupal::logger('encrypted_login')->error('AES key not found.');
+  if (!$raw_aes_key) {
+    \Drupal::logger('encrypted_login')->error('AES key decryption failed, invalid key.');
     $form_state->setError($form, t('Authentication error. Please try again.'));
     return;
   }
 
-  // Decrypt  password.
-  $password = encrypted_login_decrypt_aes($encrypted_password, $aes_key);
-
+  // Decrypt the password using the raw AES key.
+  $password = encrypted_login_decrypt_aes($encrypted_password, $raw_aes_key);
   if (empty($password)) {
     \Drupal::logger('encrypted_login')->error('Decryption failed or empty values received.');
     $form_state->setError($form, t('Invalid login credentials.'));
     return;
   }
 
-  // Set the decrypted values in the form state
+  // Set the decrypted password for further processing.
   $form_state->setValue('pass', $password);
 
-  // Remove the encrypted values to prevent them from interfering
+  // Remove the encrypted value.
   $form_state->unsetValue('encrypted_password');
-
-  // Clear any previous validation errors
   $form_state->clearErrors();
-
-}
-
-/**
- * Fetches the latest AES key from the database.
- */
-function encrypted_login_get_aes_key() {
-  $result = \Drupal::database()->select('encrypted_login_keys', 'k')
-    ->fields('k', ['aes_key'])
-    ->orderBy('created', 'DESC')
-    ->range(0, 1)
-    ->execute()
-    ->fetchAssoc();
-
-  if ($result) {
-    // Log the fetched AES key.
-    \Drupal::logger('encrypted_login')->info('Fetched AES Key Base64: @aes_key', ['@aes_key' => $result['aes_key']]);
-  }
-
-  return $result ? base64_decode($result['aes_key']) : FALSE;
 }
 
 /**
@@ -95,48 +88,35 @@ function encrypted_login_get_aes_key() {
  */
 function encrypted_login_decrypt_aes($encrypted_data, $key) {
   try {
-    // Validate input data
     if (empty($encrypted_data) || empty($key)) {
-      \Drupal::logger('encrypted_login')->error('Empty encrypted data or key provided');
+      \Drupal::logger('encrypted_login')->error('Empty encrypted data or key provided.');
       return FALSE;
     }
 
-    // First base64 decode of the entire encrypted data
     $decoded_data = base64_decode($encrypted_data, TRUE);
     if ($decoded_data === FALSE) {
-      \Drupal::logger('encrypted_login')->error('Invalid base64 encoded data');
+      \Drupal::logger('encrypted_login')->error('Invalid base64 encoded data.');
       return FALSE;
     }
 
-    // Split IV and ciphertext
     $parts = explode('::', $decoded_data, 2);
     if (count($parts) !== 2) {
-      \Drupal::logger('encrypted_login')->error('Invalid encrypted data format - missing separator');
+      \Drupal::logger('encrypted_login')->error('Invalid encrypted data format.');
       return FALSE;
     }
 
-    // Additional base64 decode for IV and ciphertext separately
     $iv = base64_decode($parts[0], TRUE);
     $ciphertext = base64_decode($parts[1], TRUE);
-
     if ($iv === FALSE || $ciphertext === FALSE) {
-      \Drupal::logger('encrypted_login')->error('Invalid base64 encoding for IV or ciphertext');
+      \Drupal::logger('encrypted_login')->error('Invalid base64 encoding for IV or ciphertext.');
       return FALSE;
     }
 
-    // Ensure the IV is exactly 16 bytes
     if (strlen($iv) !== 16) {
-      \Drupal::logger('encrypted_login')->error('Invalid IV length after decode: @length bytes (expected 16)', ['@length' => strlen($iv)]);
+      \Drupal::logger('encrypted_login')->error('Invalid IV length after decode.');
       return FALSE;
     }
 
-    // Log lengths for debugging
-    \Drupal::logger('encrypted_login')->debug('Key length: @length bytes, IV length: @iv_length bytes', [
-      '@length' => strlen($key),
-      '@iv_length' => strlen($iv),
-    ]);
-
-    // Decrypt the ciphertext
     $decrypted_data = openssl_decrypt(
       $ciphertext,
       'aes-256-cbc',
@@ -146,15 +126,14 @@ function encrypted_login_decrypt_aes($encrypted_data, $key) {
     );
 
     if ($decrypted_data === FALSE) {
-      $error = openssl_error_string();
-      \Drupal::logger('encrypted_login')->error('Decryption failed: @error', ['@error' => $error]);
+      \Drupal::logger('encrypted_login')->error('Decryption failed: ' . openssl_error_string());
       return FALSE;
     }
 
     return $decrypted_data;
   }
   catch (\Exception $e) {
-    \Drupal::logger('encrypted_login')->error('Decryption error: @message', ['@message' => $e->getMessage()]);
+    \Drupal::logger('encrypted_login')->error('Decryption error: ' . $e->getMessage());
     return FALSE;
   }
 }
diff --git a/encrypted_login.routing.yml b/encrypted_login.routing.yml
index 45e2eac6b520bd862395ea7f2aa6feb68a096da6..90b4680c10ffda2529316bb32500b483de642bb0 100644
--- a/encrypted_login.routing.yml
+++ b/encrypted_login.routing.yml
@@ -1,6 +1,6 @@
 encrypted_login.get_aes_key:
-  path: '/encrypted_login/get_aes_key'
+  path: '/encrypted_login/getPublicKey'
   defaults:
-    _controller: '\Drupal\encrypted_login\Controller\EncryptedLoginController::getAesKey'
+    _controller: '\Drupal\encrypted_login\Controller\EncryptedLoginController::getPublicKey'
   requirements:
     _permission: 'access content'
diff --git a/js/encrypted_login.js b/js/encrypted_login.js
index ebb27e6e9b4e483b7ca171bdb20a10051a59b5d6..886b02ed7532812c9eeddb1dc17999209edeba2f 100644
--- a/js/encrypted_login.js
+++ b/js/encrypted_login.js
@@ -1,35 +1,72 @@
-(function ($, Drupal) {
+(function ($, Drupal, once) {
   Drupal.behaviors.encryptedLogin = {
     attach: function (context, settings) {
-      // Fetch the AES key from the server.
-      $.get('/encrypted_login/get_aes_key', function (response) {
-        const aesKeyBase64 = response.key;
-        const aesKey = CryptoJS.enc.Base64.parse(aesKeyBase64);
-
-        $('.user-login-form').on('submit', function (event) {
-          event.preventDefault();
-
-          const password = $(this).find('#edit-pass').val();
-
-          // Generate a 16-byte IV for password encryption.
-          const ivPassword = CryptoJS.lib.WordArray.random(16);
-          const encryptedPassword = CryptoJS.AES.encrypt(
-            CryptoJS.enc.Utf8.parse(password),
-            aesKey,
-            { iv: ivPassword }
+      async function initEncryption() {
+        try {
+          const response = await $.get('/encrypted_login/getPublicKey');
+          const publicKey = response.public_key || response.key;
+          if (!publicKey) {
+            console.error("Failed to retrieve RSA public key.");
+            return;
+          }
+
+          const cryptoKey = await window.crypto.subtle.generateKey(
+            { name: "AES-GCM", length: 256 },
+            true,
+            ["encrypt", "decrypt"]
           );
-          const encryptedPasswordCombined = CryptoJS.enc.Base64.stringify(ivPassword) + '::' + encryptedPassword.toString();
+          const exportedKey = await window.crypto.subtle.exportKey("raw", cryptoKey);
+          const aesKeyBase64 = btoa(String.fromCharCode(...new Uint8Array(exportedKey)));
+
+          const aesKeyWordArray = CryptoJS.enc.Base64.parse(aesKeyBase64);
+
+          once('encrypted-login', '.user-login-form', context).forEach(function (element) {
+            $(element).on('submit', async function (event) {
+              event.preventDefault();
+              const $form = $(element);
+              const password = $form.find('#edit-pass').val();
+              if (!password) {
+                console.error("No password entered.");
+                return;
+              }
+              try {
+                const iv = CryptoJS.lib.WordArray.random(16);
+
+                const encrypted = CryptoJS.AES.encrypt(
+                  CryptoJS.enc.Utf8.parse(password),
+                  aesKeyWordArray,
+                  { iv: iv }
+                );
+
+                const ivBase64 = CryptoJS.enc.Base64.stringify(iv);
+                const encryptedPasswordCombined = ivBase64 + "::" + encrypted.toString();
+                const encryptedPasswordFinal = btoa(encryptedPasswordCombined);
+
+                const jsEncrypt = new JSEncrypt();
+                jsEncrypt.setPublicKey(publicKey);
+                const encryptedAesKey = jsEncrypt.encrypt(aesKeyBase64);
+                if (!encryptedAesKey) {
+                  console.error("RSA encryption of AES key failed.");
+                  return;
+                }
 
-          // Set encrypted values in hidden fields.
-          $('#edit-encrypted-password').val(btoa(encryptedPasswordCombined));
+                $form.find('#edit-encrypted-password').val(encryptedPasswordFinal);
+                $form.find('#edit-encrypted-aes-key').val(encryptedAesKey);
 
-          // Clear plaintext fields.
-          $('#edit-pass').val('');
+                $form.find('#edit-pass').val('');
+                $form.off('submit');
+                $form.submit();
+              } catch (error) {
+                console.error("Encryption process failed:", error);
+              }
+            });
+          });
+        } catch (error) {
+          console.error("Failed to initialize encryption:", error);
+        }
+      }
 
-          // Submit the form.
-          this.submit();
-        });
-      });
+      initEncryption();
     }
   };
-})(jQuery, Drupal);
+})(jQuery, Drupal, once);
diff --git a/src/Controller/EncryptedLoginController.php b/src/Controller/EncryptedLoginController.php
index a11d2c8f0bfe8a13015ff6536b97be7f1d3ec520..c81a054946379199e5502485a6c08a3b53a0dc7c 100644
--- a/src/Controller/EncryptedLoginController.php
+++ b/src/Controller/EncryptedLoginController.php
@@ -4,33 +4,55 @@ namespace Drupal\encrypted_login\Controller;
 
 use Drupal\Core\Controller\ControllerBase;
 use Symfony\Component\HttpFoundation\JsonResponse;
+use Drupal\Core\State\StateInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * Provides a controller for handling AES key retrieval.
+ * Provides a controller for handling RSA public key retrieval.
  */
 class EncryptedLoginController extends ControllerBase {
 
   /**
-   * Retrieves the latest AES key for client-side encryption.
+   * The state service.
+   *
+   * @var \Drupal\Core\State\StateInterface
+   */
+  protected $state;
+
+  /**
+   * Constructs a new EncryptedLoginController.
+   *
+   * @param \Drupal\Core\State\StateInterface $state
+   *   The state service.
+   */
+  public function __construct(StateInterface $state) {
+    $this->state = $state;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('state')
+    );
+  }
+
+  /**
+   * Retrieves the RSA public key for client-side encryption.
    *
    * @return \Symfony\Component\HttpFoundation\JsonResponse
-   *   A JSON response containing the AES key or an error message.
+   *   A JSON response containing the RSA public key or an error message.
    */
-  public function getAesKey() {
-    // Fetch the latest AES key from the 'encrypted_login_keys' table.
-    $key = \Drupal::database()->select('encrypted_login_keys', 'k')
-      ->fields('k', ['aes_key'])
-      ->orderBy('created', 'DESC')
-      ->range(0, 1)
-      ->execute()
-      ->fetchField();
-
-    // Return the AES key if found, otherwise return an error response.
-    if ($key) {
-      return new JsonResponse(['key' => $key]);
+  public function getPublicKey(): JsonResponse {
+    // Fetch the RSA public key from Drupal's state API.
+    $public_key = $this->state->get('encrypted_login.rsa_public_key');
+
+    if ($public_key) {
+      return new JsonResponse(['public_key' => $public_key]);
     }
 
-    return new JsonResponse(['error' => 'AES key not found.'], 500);
+    return new JsonResponse(['error' => 'RSA public key not found.'], 500);
   }
 
 }