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 Nitrokey Pro and PKCS#11 support [$520] #255

Open
Germano0 opened this issue Feb 4, 2017 · 136 comments
Open

Add Nitrokey Pro and PKCS#11 support [$520] #255

Germano0 opened this issue Feb 4, 2017 · 136 comments

Comments

@Germano0
Copy link
Contributor

Germano0 commented Feb 4, 2017

Nitrokey Pro is an Open Hardware device and FOSS software that allows people to use such device as a secure token for various security needs, like two factor authentication, GPG/PGP, SSH keys, etc.
It would be great to have support for such device

@albrechtd
Copy link

I think this extension would be extremely useful and thus I strongly support this suggestion.

Maybe you know that there has been a somewhat similar Feature Request for keypassx in 2010. The workaround using the gpg pipe doesn't work for me, though.

Instead of directly interfacing to a smartcard, an alternative could be a gpg-encrypted keyfile which is fed through gpgme which in turn uses the gpg key from any smartcard.

@droidmonkey
Copy link
Member

I wish these devices used the PKCS#11 standard like smart cards.... I am not keen to include the libraries of all the various hardware tokens out in the world.

@Germano0
Copy link
Contributor Author

@droidmonkey
Copy link
Member

Hmmmm i wonder if we could just create a pkcs#11 module instead and then you could also use smart cards /pivs

@drdaeman
Copy link

I have a Gnuk-based FST-01, which should be quite similar to Nitrokey Start. I think while it works as OpenPGP Card v2, it doesn't really work as PKCS#11, at least not without something like Scute. I.e. gpg --card-status works out-of-box, but pkcs11-tool --show-info fails with CKR_DEVICE_ERROR. Maybe that's just me not understanding something, though.

How about an option of having an encrypted keyfile and talking to GnuPG (via GPGME or whatever), letting it handle the actual hardware, whatever it is? (Or maybe even a generic option of an external keyfile material provider using pipes?) Something similar in spirit to the linked KeepassX feature request, but with auth process explicitly started and controlled by KeepassXC.

@livelace

This comment has been minimized.

@droidmonkey

This comment has been minimized.

@livelace

This comment has been minimized.

@AzureRaptor
Copy link

I'm also interested in seeing any support, PKCS or otherwise, that would let us use NitroKeys. I started to look at getting a YubiKey recently, but it seems like they are turning their backs on open source just lately, and their excuses are all very facile and shady.

@droidmonkey
Copy link
Member

I noticed their GitHub is not very organized.

@rhetr
Copy link

rhetr commented Feb 23, 2018

https://github.com/Nitrokey/nitrokey-keepass-plugin they have a plugin repo for keepass with no documentation ✌

@protobits
Copy link

It would be also interesting for me to have support for Gnuk-based device. This would involve talking to gpg-agent for authentication. I understand this uses a standard protocol.

@phoerious
Copy link
Member

We cannot use Nitrokeys directly, because they do not support HMAC-SHA1. We have some ideas for supporting PGP-encrypted keys, but it will take some time to implement then.

@szszszsz
Copy link
Contributor

Hi! Just noticed this issue and I thought I could reply some questions regarding Nitrokey.

@droidmonkey Nitrokeys support PKCS#11 with OpenSC.

@drdaeman PKCS#11 with Nitrokey Start was used in Raymii's tutorial - maybe you would find this helpful. See guides from official Nitrokey's site as well.

@rhetr I do not know the details, but this is an attempt to use PKCS#11 in Keepass2. It perhaps worked 5 years ago, but I am not so sure about it right now. Good point to mention that in Readme.

@phoerious We support HOTP at the moment. Maybe we could work something out with it, like using HOTP codes in encryption of the database (similarly to Keepass2 solution)?
In the future we could support HMAC-SHA1 directly, if there would be a request (no one registered it in Pro's firmware project yet).

Love the project - all the best!

@livelace

This comment has been minimized.

@phoerious
Copy link
Member

We haven't had time for working on the PGP thing yet, there are too many other more urgent things that need to be done first, but it's on the agenda.
HOTP is basically just manual HMAC-SHA1. We could support it. I was also thinking to provide some sort of HMAC-SHA1 backup function where you enter the secret directly and let KeePassXC generate the challenge from it. That way you can still access the database if you lost your key, but still know its secret.

@jans23
Copy link

jans23 commented Jun 2, 2018

@phoerious Let me know if there is anything we at Nitrokey could do to support you.

@svenseeberg
Copy link

@jans23 I started working on this issue. However, libnitrokey has a steep learning curve (as has KeepassXC). Anyways, I do not understand how to connect to a Nitrokey while the Nitrokey app is running. Or put differently: NitrokeyManager->connect() only works while the Nitrokey app is not running. How do I solve this?

@szszszsz
Copy link
Contributor

@svenseeberg Current protocol is not designed to be used for multiple applications thus opening in libnitrokey blocks further connections. Do you have a specific need to have both Nitrokey App and KeepassXC opened at the same time?

@svenseeberg
Copy link

svenseeberg commented Aug 10, 2018

@szszszsz Thanks for getting back to me that quick. No, there is no specific need. It's just about usability. Maybe I'll add a function that detects whether the app is running and notifies the user. And I guess that the user could manually copy the one time pad if both programs are being used at the same time.

*edit: Now that I know that both programs cannot use a Nitrokey at the same time, I think I'll only implement a manual HOTP method. That means the user has to manually copy the shared secret and one time pads from the Nitrokey App to KeepassXC. Better ideas?

@szszszsz
Copy link
Contributor

OK! Detecting solution as you speak should work (maybe supported with libusb). Perhaps adding such function directly to libnitrokey would be handy - if so, please register an issue there. Let me know if you would need any help with the library - I will happily support you. I have added myself to the fork watchers, so we could discuss issues there as well.

@svenseeberg
Copy link

svenseeberg commented Aug 10, 2018

Sorry for causing confusion. HOTP is no use because the shared secret would have to be stored unencrypted along the kdbx file. So we're back at waiting for PKSC11 support.

@droidmonkey droidmonkey changed the title Nitrokey Pro support Add Nitrokey Pro and PCKS#11 support Sep 5, 2018
@jornfranke
Copy link

I would be also curios. One simple way could be also to add an option to add one or more gpg keys (I expect that one user has multiple openpgp smartcards in case one is lost) using the command line version of gpg. Then you have already multiple smart integrations out of the box. The users would just need to install gpg, but this can be optionally. I would think that most of the people with Nitrokey Pro or other openpgp smartcards have gpg already installed for sure.

@smesguich-orange
Copy link

Hello !
Very intrested of this feature !

@florianutz
Copy link

@droidmonkey

BTW, with my conversion of keepassxc to using Botan we are MUCH closer to integrating PKCS#11 in a standard, cross-platform manner. I anticipate this being implemented for 2.7.0 along with the Ledger key support.

Do you have any idea when it will be implemented? We are now at 2.7.1

@yan12125
Copy link
Contributor

(From #255 (comment))

It would be best to treat PKCS11 similar to Yubikey Challenge-Response where you provide a random token to the PKCS11 device which returns a transformed/signed version that is then added to the master key material.

I managed to sign data using Botan and PKCS#11 after reading some docs/examples. I don't have time to push it further recently, so I paste my current progress below. Hope it helps :)

Codes that signs data with an RSA private key.
#include <cstdint>
#include <string>
#include <iostream>
#include <iomanip>
#include <botan/auto_rng.h>
#include <botan/pubkey.h>
#include <botan/p11_rsa.h>
#include <botan/p11_types.h>
#include <botan/p11_object.h>

// echo -n yay | openssl dgst -engine pkcs11 -keyform ENGINE -sign 'pkcs11:token=OpenPGP%20card%20%28User%20PIN%29;id=%03;object=Authentication%20key;type=private' | od -x --endian=big
int main() {
    Botan::PKCS11::Module pkcs11_module("/usr/lib/pkcs11/opensc-pkcs11.so");
    std::vector<Botan::PKCS11::SlotId> slots = Botan::PKCS11::Slot::get_available_slots(pkcs11_module, true );
    // use first slot
    Botan::PKCS11::Slot slot( pkcs11_module, slots.at( 0 ) );
    Botan::PKCS11::SlotInfo slot_info = slot.get_slot_info();
    std::cout << std::to_string( slot_info.firmwareVersion.major ) << "."
              << std::to_string( slot_info.firmwareVersion.minor ) << std::endl;
    Botan::PKCS11::Session read_only_session( slot, true );
    Botan::PKCS11::secure_string pin = { '1', '2', '3', '4', '5', '6' };
    read_only_session.login( Botan::PKCS11::UserType::User, pin );
    const auto& objs = Botan::PKCS11::Object::search<Botan::PKCS11::PKCS11_RSA_PrivateKey>(read_only_session, std::string("Authentication key"));
    std::cout << objs.size() << std::endl;
    if (!objs.size()) {
        std::cout << "No objects found!" << std::endl;
    } else {
        const Botan::PKCS11::PKCS11_RSA_PrivateKey& obj = objs.at(0);
        for (uint8_t c : obj.get_attribute_value(Botan::PKCS11::AttributeType::Id)) {
            std::cout << std::hex << std::setfill('0') << std::setw(2) << static_cast<uint16_t>(c) << ":";
        }
        std::cout << std::endl;

        Botan::Null_RNG rng;
        // EMSA4 for RSA uses PSS (probabilistic signature scheme)
        Botan::PK_Signer signer( obj, rng, "EMSA3(SHA-256)", Botan::IEEE_1363 );
        Botan::PKCS11::secure_string plaintext = { 'y', 'a', 'y' };
        const auto& signature = signer.sign_message( plaintext, rng );
        for (const unsigned char c : signature) {
            std::cout << std::hex << std::setfill('0') << std::setw(2) << static_cast<uint16_t>(c) << ":";
        }
        std::cout << std::endl;
    }

    read_only_session.logoff();
}

Tested with Nitrokey Start. Here I use an RSA key instead of an Ed25519 key as Botan API does not support it yet. Botan docs mentions

The Botan PKCS#11 interface is implemented against version v2.40 of the standard.

while Ed25519 support is added in PKCS#11 v3.0

@droidmonkey
Copy link
Member

I thought of a major problem with pkcs#11 and the nature of PKI which is NOT meant to be static. When your cert expires and you get a new one or a new card you will be locked out of your database. So unless we are strictly doing certificate validation... PKCS#11 is not a good choice for an offline database.

@yan12125
Copy link
Contributor

I think I only need the private key to sign data for using as a keepassxc master key material, and a certificate is not needed? I don't use a certificate in the example above. I can keep the current master key as long as I keep the PKCS#11-capable hardware key, just like how KeePassXC works for Yubikey-like keys.

@My1
Copy link

My1 commented Oct 22, 2022

Can't pkcs11 also be used to en/decrypt stuff? Because with signing there might be a chance there's some randomness added or whatever for security which would 100% break this idea. Also not sure if there can be certs or just keys which don't even expire. And in fact expiry doesn't really matter even if keypass checks it as you need to keep in mind that the database is already in hands of the attacker so they could just decrypt it manually after getting the signature/decrypted value.

Any kinds of 'smart play' would basically amount to snake oil.

@yan12125
Copy link
Contributor

The PKCS#11 v3.0 standard does mention encryption/decryption. I believe Botan also supports that but I don't have time to verify it recently.

@droidmonkey
Copy link
Member

Encrypt/decrypt and signing would produce the same failure if the underlying private key changes. You also don't want to encrypt anything of large size with the on-board chip of a pkcs#11 device.

@My1
Copy link

My1 commented Oct 22, 2022

yes if the key changes there'll be a problem. simple solution, dont change that key. (except in a scenario where you have the DB open for re-keying obviously)
I dont know all smartcards obviously but those that I know usually have multiple slots so set one up specifically for keepass to just not change.

the problem is any scenario where you wanna have the ability to change your key with basically no notice requires a method to disallow the data to be processed/transmitted/whatever in a robust manner, purely on a verify, basically a data valve.

This however only works where you actually can stop the data flow in that manner. for example when you sign into your nextcloud, your nextcloud could deny sending you the data.

where a verify-based approach does NOT work is when you already have the data to be processed and the process is known, say a password database, a master password and an open source password manager.

because you could either fork the program and patch out the verify, do the decryption yourself, or if you are really crazy, just knock out the verify in RAM in case the program isnt open source.

It is the same reason why you should not use TOTP for data/password vaults. (yes this is literally 5 years old and they are still doing it XD)

@livelace
Copy link

It's worthy to check out systemd pkcs11 support implementation - https://www.freedesktop.org/software/systemd/man/systemd-cryptenroll.html

I use Rutoken HSM for unlocking LUKS, as soon as my certificate will finally expired (10 years, btw) - I have an option to unlock LUKS with regular passphrase (backup mechanism).

The main point of using HSM - don't let passphrase to be leaked, keep secrets in a safe place.

@droidmonkey
Copy link
Member

yes if the key changes there'll be a problem. simple solution, dont change that key.

This only applies in cases where you have control over your key. If you use an employers smart card or a government card there is no guarantee your key won't change if you lose your card or have to get it renewed. Also if you are using certificates your key will expire at some point and will be changed.

@My1
Copy link

My1 commented Oct 22, 2022

This only applies in cases where you have control over your key.

either that or the person who does have control is aware and/or you can work with them about that.

If you use an employers smart card or a government card there is no guarantee your key won't change if you lose your card or have to get it renewed.

if it's not even your card then maybe it's not the best idea to use it. Also, if your employer wants you to use the card for keypass there are ways to get around:

  1. have the employer have a backup of that key (especially useful if needed to provision that to multiple ppl anyway for example in case of a team safe, in fact that's also a great way if you wanna ensure the people who can access the safe dont have access to the key on the card itself but are only able to use it, take the smartcard away and the access is revoked by at worst rotating the DB master key while still allowing the smartcards with the key to unlock seamlessly)
  2. have a backup of the key yourself and get it onto that card if the employer allows that
  3. have a backup procedure to get into the safe for rekeying

Also if you are using certificates your key will expire at some point and will be changed.

That's technically not true. the cert expires and you can make a new cert onto the same key if you still trust it.

also as said smartcards can have multiple slots so you can use one like a proper cert with expiry rekeying and all and another slot just for keepass.

@ffries
Copy link

ffries commented Nov 20, 2022

+1

I am using OpenSC smartcards and any OpenSC smartcard should do the job.
OpenSC is supported on all systems. It is today's world standard.

OpenSC smartcards allow to store an AES/GPG key and retrieve it with PIN protection.
But the best would be to keep the AES key secure and derive the key using the smartcard.

https://www.smartcard-hsm.com/features.html#smartcard

EC Key Derive
In particular for crypto currencies and smart contracts, the SmartCard-HSM supports derived EC keys to implement key management schemes similar to BIP32. Unlike with BIP32, key material remains inside the secure element, while the public key can be calculated outside from the master public key.

The Smartcard-HSM card works pretty well and is probably the most advanced OpenSC smartcard available, is both contact and contactless (and the cheapest):
https://www.smartcard-hsm.com/

There are also several open-source implementations of OpenSC smartcards.
Example: French National Security Agency OpenGPG smartcard (compatible with OpenSC):
https://github.com/ANSSI-FR/SmartPGP

The advantage of smartcards over USB keys is that they can be used with PINPAD readers.
A good CCID pinpad reader with secure messaging (don't buy without secure messaging) costs 30€ and is unbreakable.
secure messaging makes sure that PIN code is transmitted securely beetween pinpad and reader.

Example : SCM SPR332 : v1 around 20€ used and v2 around 50€ new.
https://www.floss-shop.de/en/security-privacy/smartcard-reader/26/scm-spr332-v2-pinpad-reader

Any CCID pinpad is supported out of the box without need for drivers on all systems.
See CCID website for reference: https://ccid.apdu.fr/

Unfortunately Yubikey is a nice product name but offers no pinpad so no real security.
Same as for Nitokey, it is not real security.

@ffries
Copy link

ffries commented Nov 27, 2022

By the way, I just discovered that the Nitrokey is based on the smartcard-hsm.
The Key / smartcard offers full support for PKCS#11 on Linux, Mac and Windows using OpenSC.

https://www.smartcard-hsm.com

OpenSC offers rock-solid APIs and PKCS#11 libraries.

https://github.com/OpenSC/OpenSC

So it should be the way to go ...

hmac-sha1 is deprecated. The PKCS#11 supports several ways to derive a key and/or calculate a SHA-256 challenge-response.

This thread should be renamed to: Add PKCS#11 support for smartcards encryption/decryption/signature

@frankmorgner
Copy link

Actually, you want to use a platform dependant method for using a token to minimize friction for the user.

For Windows, you should start here:
https://keepass.info/plugins.html#certkeyprov
Use MS Crypto API to decrypt the master password. This will work for any token provider, not just OpenSC and it allows full compatibility with existing databases.

For macOS, you should use CryptoTokenKit and only on Unix you should use PKCS#11

@igor-krawczuk
Copy link

Hi, where can I add cash for this bounty? Is it simply pledging or is there a blessed platform like bountysource, issuehunt etc. that is being used?

@droidmonkey
Copy link
Member

We don't endorse any bounty system anymore

@florianutz
Copy link

I dropped my money on bountysource two years ago but it didn't help this feature move forward.

@ncorder
Copy link

ncorder commented Apr 4, 2023

Bountysource


not entirely certain what the thought process on bounty source was here but wanted to add the widget

@smesguich-orange
Copy link

Hello,

I see that feature doesn't moove forward, I didn't get all why it's still stuck ?
Also, bounty system is done ? So Bad ...

@rugk
Copy link

rugk commented Jul 31, 2023

Support for NitroKey 3 (I assume it is the same product as the "NitroKey Pro 3") has been added in this PR apparently (just not linked):
#9631

So I guess it should be included in the next release… 👀 🎉

@florianutz
Copy link

@rugk

Support for NitroKey 3 (I assume it is the same product as the "NitroKey Pro 3") has been added in this PR apparently (just not linked): #9631

So I guess it should be included in the next release… 👀 🎉

#9631 is about challenge-response but not PKCS#11 what this thread is about

@jinnko
Copy link

jinnko commented Mar 8, 2024

For what it's worth, OpenSC can use the openpgp inteface to access keys stored on an openpgp smartcard.

With that opensc config in place it's possible to load a GPG key from a smartcard such as a Yubikey into the ssh-agent with ssh-add -s /usr/lib/pkcs11/opensc-pkcs11.so ~/.ssh/id_rsa-yubikey.pub.

Could KeepassXC interface with the ssh-agent in a similar way to manage the key in the ssh-agent?

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