Created
July 7, 2024 21:15
-
-
Save quad/52097432c02baaaedcb87d245f7582b3 to your computer and use it in GitHub Desktop.
How to sign messages with secp256k1 on a YubiKey
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from cryptography.hazmat.primitives.asymmetric.ec import ECDSA | |
from cryptography.hazmat.primitives.hashes import SHA256 | |
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat | |
from ykman.device import list_all_devices | |
from ykman.logging import init_logging | |
from yubikit.core import TRANSPORT | |
from yubikit.core.smartcard import SmartCardConnection | |
from yubikit.logging import LOG_LEVEL | |
from yubikit.management import CAPABILITY | |
from yubikit.openpgp import EcAttributes, KEY_REF, OID, OpenPgpSession | |
# Uncomment this to see what goes over the wire | |
#init_logging(LOG_LEVEL.TRAFFIC) | |
device, info = [ | |
(device, info) | |
for device, info in list_all_devices() | |
if CAPABILITY.OPENPGP in info.supported_capabilities.get(TRANSPORT.USB, []) | |
][0] | |
def is_secp256k1_ecattr(attr): | |
return isinstance(attr, EcAttributes) and attr.oid == OID.SECP256K1 | |
with device.open_connection(SmartCardConnection) as connection: | |
openpgp = OpenPgpSession(connection) | |
if not is_secp256k1_ecattr(openpgp.get_algorithm_attributes(KEY_REF.SIG)): | |
print("Generating secp256k1 key in SIG slot...") | |
openpgp.verify_admin("12345678") | |
openpgp.generate_ec_key(KEY_REF.SIG, OID.SECP256K1) | |
public_key = openpgp.get_public_key(KEY_REF.SIG) | |
public_key_sec = public_key \ | |
.public_bytes(Encoding.X962, PublicFormat.CompressedPoint) \ | |
.hex() | |
print(f"SIG slot secp256k1 public key: {public_key_sec}") | |
print("Signing with secp256k1 key in SIG slot...") | |
data = b"abc123" | |
openpgp.verify_pin("123456") | |
signature = openpgp.sign(data, SHA256()) | |
print(f"Signature: {signature.hex()}") | |
public_key.verify(signature, data, ECDSA(SHA256())) | |
print("OK") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment