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

Import passkeys from Bitwarden JSON-export #10775

Closed
borque opened this issue May 18, 2024 · 14 comments · Fixed by #11401
Closed

Import passkeys from Bitwarden JSON-export #10775

borque opened this issue May 18, 2024 · 14 comments · Fixed by #11401

Comments

@borque
Copy link

borque commented May 18, 2024

Overview

When exporting Bitwardens database at least the current version 2024.4.3 seems to include passkeys.
Unfortunately when importing such a JSON-export into KeePass 2.7.8 the passkeys are not present afterwards,

Steps to Reproduce

  1. Export a Bitwarden-database with passkeys to a JSON file using 2024.4.3
  2. Import this database into KeepAss 2.7.8 using the Bitwarden-importer offered when creating a database

Expected Behavior

KeePassXC should also import the passkeys and they should be usable in the newly created KeepAssXC-database.

Actual Behavior

The passkeys are missing or are at least not accessible in KeePassXC after import.

Context

Below is a quote from the JSON file that shows that the passkeys are (or at least seem to be) included.
I have removed (REDACTED) all personal information from it.
As long as the automatic import seems impossible: Which parts do I need to provide when re-creating my passkeys manually in KeepAssXC? Two fields, keyValue and userHandle, contain data looking like cryptographic material.

"login": {
        "fido2Credentials": [
          {
            "credentialId": "***R*E*D*A*C*T*E*D***",
            "keyType": "public-key",
            "keyAlgorithm": "ECDSA",
            "keyCurve": "P-256",
            "keyValue": "***R*E*D*A*C*T*E*D***",
            "rpId": "***R*E*D*A*C*T*E*D***",
            "userHandle": "***R*E*D*A*C*T*E*D***",
            "userName": null,
            "counter": "6",
            "rpName": "***R*E*D*A*C*T*E*D***",
            "userDisplayName": "***R*E*D*A*C*T*E*D***",
            "discoverable": "true",
            "creationDate": "***R*E*D*A*C*T*E*D***"
		  }
		  ]
}

KeePassXC - 2.7.8
Operating System: Windows

@borque borque added the bug label May 18, 2024
@droidmonkey
Copy link
Member

droidmonkey commented May 18, 2024

great thank you for the snippet, we don't import them because this export of passkeys from Bitwarden is brand new.

To manually import you need to transcribe the following:

image

My best guess is the following mapping:

credentialId -> KPEX_PASSKEY_CREDENTIAL_ID
rpId -> KPEX_PASSKEY_GENERATED_USER_ID
userHandle -> KPEX_PASSKEY_USER_HANDLE
keyValue -> KPEX_PASSKEY_PRIVATE_KEY_PEM
rpName -> KPEX_PASSKEY_RELYING_PARTY
userName -> KPEX_PASSKEY_USERNAME

Since they are exporting the key type, algorithm, and curve I bet the keyValue is not in PEM format...

@droidmonkey
Copy link
Member

droidmonkey commented May 18, 2024

Can you create a throw away passkey in Bitwarden on https://webauthn.me and export that with the actual values in tact?

You can make a bunch with different key types as well to help us with the import values.

@droidmonkey droidmonkey added this to the v2.8.0 milestone May 18, 2024
@droidmonkey droidmonkey self-assigned this May 18, 2024
@droidmonkey droidmonkey changed the title KeePassXC 2.7.8 does not import passkeys from Bitwardens JSON-export Import passkeys from Bitwarden JSON-export May 18, 2024
@varjolintu
Copy link
Member

Wait, Bitwarden now exports passkeys in unencrypted form?

@borque
Copy link
Author

borque commented May 19, 2024

I will try to generate keys with different algorithms in WebAuthn's debugging mode in a Bitwarden test-account the coming week.

One interesting thing -and the one that keeps me away from publishing results of my current WebAuth-testing with my real Bitwarden-vault- is, that the first 47 characters in the keyValue-field seem to be the same for all passkeys (not only those for WebAuthn) I have generated so far.

All of these passkeys use ECDSA and P-256, so it could just be related to the algorithms used, but I'm not sure.

@hu3rror
Copy link

hu3rror commented May 26, 2024

Can you create a throw away passkey in Bitwarden on https://webauthn.me and export that with the actual values in tact?

You can make a bunch with different key types as well to help us with the import values.

The exported results from Bitwarden are as follows:

      "login": {
        "fido2Credentials": [
          {
            "credentialId": "a2e10494-af23-400c-8146-23234e1830ed",
            "keyType": "public-key",
            "keyAlgorithm": "ECDSA",
            "keyCurve": "P-256",
            "keyValue": "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgm5wxMck_Y4iqwK1KxjCjC89uE6ihcxdIoJxWRpr5fQGhRANCAAQxzERjKfkI1v5ME327S1niSKqEKXhx9O-1IJLTmyY7MIX6jfpErxbphBdfZ4T8HH5UyMmwSiaKMWzuEex3FsP_",
            "rpId": "webauthn.me",
            "userHandle": "4CGQVa5pj3VuDgQK2yCjSwoa2VDOC5kfWYsvfgRm1AU",
            "userName": "test",
            "counter": "0",
            "rpName": "Auth0 WebAuthn Playground",
            "userDisplayName": "test",
            "discoverable": "false",
            "creationDate": "2024-05-26T05:59:13.483Z"
          }
        ],
        "uris": [
          {
            "match": null,
            "uri": "https://webauthn.me/"
          }
        ],
        "username": null,
        "password": null,
        "totp": null
      },

I also added the passkey using the same username 'test' in KeepassXC, and here are the results:

  • KPEX_PASSKEY_CREDENTIAL_ID: g5IQ80lBIUo1FJNYwwh28US6o0576X_Fg1qQfR4AJGE
  • KPEX_PASSKEY_PRIVATE_KEY_PEM:
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg1wOBQ37VMFek9Ol9
vNgxxVkGa/+rwrm0kK8FS56OFsShRANCAARczvnTsLOLQDtka0+HkrG/PG/5f4eB
s8l95Jxc5ffzBy4PY01bxqpQhq5Yiur3JaE95WIdXj6MrUhIwCDlRDen
-----END PRIVATE KEY-----
  • KPEX_PASSKEY_RELYING_PARTY: webauthn.me
  • KPEX_PASSKEY_USERNAME: test
  • KPEX_PASSKEY_USER_HANDLE: FTEQqZV77CcL9L_9LDtbHByB0tT8wXDSdklCA6_0b6E

As you can see, the format is consistent, with the exception of the credentialId and KPEX_PASSKEY_CREDENTIAL_ID. The Bitwarder is in UUID format, while 's KPEX_PASSKEY_CREDENTIAL_ID appears to be an encrypted value hashed?

@varjolintu
Copy link
Member

varjolintu commented May 26, 2024

@hu3rror Credential ID is usually generated when a passkey is registered. According to this line, they might be using GUID for it by default:
https://github.com/bitwarden/clients/blob/89d7e96b25594e51a7e8db6b227f06aeab79c543/libs/common/src/platform/services/fido2/fido2-client.service.spec.ts#L334
https://github.com/bitwarden/clients/blob/89d7e96b25594e51a7e8db6b227f06aeab79c543/libs/common/src/platform/services/fido2/guid-utils.ts#L14

The example value a2e10494-af23-400c-8146-23234e1830ed after parsing and base64 encode should be: ouEElK8jQAyBRiMjThgw7Q.

@droidmonkey
Copy link
Member

droidmonkey commented May 26, 2024

The value are in Base64 encoding

@borque
Copy link
Author

borque commented May 26, 2024

Hello!
I have created an additional Bitwarden account for testing purposes. Do you still need new passkey exports, or were you abled to get the necessary information from Bitwardens documentation? And if you need, do you want to see keys generated with different algos, or user names or …?
Or can I as a mere user be of any other help here?

@droidmonkey
Copy link
Member

If you can help create keys with different algorithms or curves that would be very helpful

@borque
Copy link
Author

borque commented Jun 1, 2024

I created another passkey on https://webauthn.me/ . Passkey generation with Bitwarden only works with the default settings on the landing page for me. When selecting other combinations in webauthn's debug mode the page reports that no supported algorithms are found. I don't know whether Bitwarden lacks support for other curves etc..
I attach both, the json export and the params webauthn.me reports to have used for passkey generation.
Hope this helps you at least a bit.

passkey_test.json
passkey_test.txt

@querylab
Copy link

Hello everyone, I am working on a Python script to import data from Bitwarden to KeePassXC and I am encountering the same issue described: the passkeys are not being imported correctly into KeePassXC. Has there been any progress or solution to this problem?

@varjolintu
Copy link
Member

I just successfully managed to import a passkey from Bitwarden to KeePassXC. The process was still quite manual, but I'll work a PR for the importer.

@hex-m
Copy link

hex-m commented Oct 24, 2024

There is an upcoming standard called Credential Exchange Format (CXF). As Bitwarden is part of the special interest group, I assume they will implement this too.

https://fidoalliance.org/fido-alliance-publishes-new-specifications-to-promote-user-choice-and-enhanced-ux-for-passkeys/

@varjolintu
Copy link
Member

There is an upcoming standard called Credential Exchange Format (CXF). As Bitwarden is part of the special interest group, I assume they will implement this too.

https://fidoalliance.org/fido-alliance-publishes-new-specifications-to-promote-user-choice-and-enhanced-ux-for-passkeys/

We are aware. There's already an issue open: #11363

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

Successfully merging a pull request may close this issue.

6 participants