diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js
--- a/lib/actions/user-actions.js
+++ b/lib/actions/user-actions.js
@@ -120,12 +120,8 @@
   ): ((logInInfo: LogInInfo) => Promise<LogInResult>) =>
   async logInInfo => {
     const watchedIDs = threadWatcher.getWatchedIDs();
-    const {
-      logInActionSource,
-      primaryIdentityPublicKeys,
-      notificationIdentityPublicKeys,
-      ...restLogInInfo
-    } = logInInfo;
+    const { logInActionSource, signedIdentityKeysBlob, ...restLogInInfo } =
+      logInInfo;
 
     const response = await callServerEndpoint(
       'log_in',
diff --git a/lib/types/account-types.js b/lib/types/account-types.js
--- a/lib/types/account-types.js
+++ b/lib/types/account-types.js
@@ -1,6 +1,6 @@
 // @flow
 
-import type { OLMIdentityKeys } from './crypto-types.js';
+import type { SignedIdentityKeysBlob } from './crypto-types.js';
 import type { PlatformDetails } from './device-types.js';
 import type {
   CalendarQuery,
@@ -105,8 +105,7 @@
   +calendarQuery: CalendarQuery,
   +deviceTokenUpdateRequest?: ?DeviceTokenUpdateRequest,
   +primaryIdentityPublicKey?: string,
-  +primaryIdentityPublicKeys?: ?OLMIdentityKeys,
-  +notificationIdentityPublicKeys?: ?OLMIdentityKeys,
+  +signedIdentityKeysBlob?: SignedIdentityKeysBlob,
 };
 
 export type LogInInfo = {
diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js
--- a/lib/types/crypto-types.js
+++ b/lib/types/crypto-types.js
@@ -16,3 +16,8 @@
   +notificationAccount: ?PickledOLMAccount,
   +notificationIdentityKeys: ?OLMIdentityKeys,
 };
+
+export type SignedIdentityKeysBlob = {
+  +payload: string,
+  +signature: string,
+};
diff --git a/web/account/traditional-login-form.react.js b/web/account/traditional-login-form.react.js
--- a/web/account/traditional-login-form.react.js
+++ b/web/account/traditional-login-form.react.js
@@ -1,5 +1,6 @@
 // @flow
 
+import olm from '@matrix-org/olm';
 import invariant from 'invariant';
 import * as React from 'react';
 
@@ -15,7 +16,11 @@
   LogInStartingPayload,
 } from 'lib/types/account-types.js';
 import { logInActionSources } from 'lib/types/account-types.js';
-import type { OLMIdentityKeys } from 'lib/types/crypto-types.js';
+import type {
+  OLMIdentityKeys,
+  PickledOLMAccount,
+  SignedIdentityKeysBlob,
+} from 'lib/types/crypto-types.js';
 import {
   useDispatchActionPromise,
   useServerCall,
@@ -44,6 +49,9 @@
   const notificationIdentityPublicKeys: ?OLMIdentityKeys = useSelector(
     state => state.cryptoStore.notificationIdentityKeys,
   );
+  const primaryAccount: ?PickledOLMAccount = useSelector(
+    state => state.cryptoStore.primaryAccount,
+  );
 
   const usernameInputRef = React.useRef();
   React.useEffect(() => {
@@ -79,14 +87,30 @@
           notificationIdentityPublicKeys,
           'notificationIdentityPublicKeys must be set in logInAction',
         );
+        invariant(primaryAccount, 'primaryAccount must be set in logInAction');
+
+        const primaryOLMAccount = new olm.Account();
+        primaryOLMAccount.unpickle(
+          primaryAccount.picklingKey,
+          primaryAccount.pickledAccount,
+        );
+
+        const payloadToBeSigned = JSON.stringify({
+          primaryIdentityPublicKeys,
+          notificationIdentityPublicKeys,
+        });
+        const signedIdentityKeysBlob: SignedIdentityKeysBlob = {
+          payload: payloadToBeSigned,
+          signature: primaryOLMAccount.sign(payloadToBeSigned),
+        };
+
         const result = await callLogIn({
           ...extraInfo,
           username,
           password,
           logInActionSource: logInActionSources.logInFromWebForm,
           primaryIdentityPublicKey: primaryIdentityPublicKeys.ed25519,
-          primaryIdentityPublicKeys,
-          notificationIdentityPublicKeys,
+          signedIdentityKeysBlob,
         });
         modalContext.popModal();
         return result;
@@ -107,6 +131,7 @@
       modalContext,
       notificationIdentityPublicKeys,
       password,
+      primaryAccount,
       primaryIdentityPublicKeys,
       username,
     ],
@@ -194,6 +219,8 @@
             primaryIdentityPublicKeys === undefined ||
             notificationIdentityPublicKeys === null ||
             notificationIdentityPublicKeys === undefined ||
+            primaryAccount === null ||
+            primaryAccount === undefined ||
             inputDisabled
           }
           onClick={onSubmit}