Keys#
Nxpcrypto, a component of SPSDK (Secure Provisioning SDK), offers a suite of utilities for cryptographic operations. This Jupyter notebook guides you through the process of generating cryptographic keys using nxpcrypto, with a specific focus on Elliptic Curve Cryptography (ECC) keys.
Cryptographic keys are fundamental to secure communication and data protection. They come in two main types:
Symmetric keys: Used in algorithms where the same key is used for both encryption and decryption.
Asymmetric keys: Consist of a key pair - a public key for encryption and a private key for decryption.
In this guide, we’ll concentrate on generating asymmetric key pairs, specifically ECC keys. ECC is a modern approach to public-key cryptography based on the algebraic structure of elliptic curves over finite fields. It offers smaller key sizes and faster computations compared to RSA while maintaining equivalent security levels.
Key management best practices:#
Generate unique keys for each project or application.
Store keys securely, preferably in a hardware security module (HSM) or a secure key management system.
Protect private keys with strong passwords or encryption.
Implement access controls to limit who can use or manage the keys.
Remember, the security of your entire system often depends on the security of your cryptographic keys. Treat them with utmost care and follow industry best practices for key management.
Supported Key types#
RSA
2048-bit (rsa2048)
3072-bit (rsa3072)
4096-bit (rsa4096)
ECC
secp256r1
secp384r1
secp521r1
Chinese national cryptography standards
sm2
Post Quantum
dilithium2
dilithium3
dilithium5
Now, let’s proceed with generating keys using nxpcrypto in our Jupyter notebook.
1. Prerequisites#
SPSDK is needed with examples extension.
pip install spsdk[examples]
(Please refer to the installation documentation.)
Let’s prepare also workspace and variables.
# Initialization cell
import os
# This env variable sets colored logger output to STDOUT
%env JUPYTER_SPSDK=1
# Set a magic for command execution and echo
%alias execute echo %l && %l
%alias_magic ! execute
env: JUPYTER_SPSDK=1
Created `%!` as an alias for `%execute`.
WORKSPACE = "workspace/" # change this to path to your workspace
VERBOSITY = (
"-v" # verbosity of commands, might be -v or -vv for debug or blank for no additional info
)
2. Keys Generation#
This section is used for key generation. Each time the keys generate command is called, an asymmetric key pair is generated. Key pair includes a public key (.pub) and a corresponding private key (.pem).
2.1 Generate Keys with nxpcrypto CLI#
The nxpcrypto application provides command line interface which can be used for key generation as well as for verification generated key pair.
KEY_TYPE = "secp256r1"
ROTK_PRIVATE_KEY_PATH = WORKSPACE + f"srk0_{KEY_TYPE}.pem"
ROTK_PUBLIC_KEY_PATH = WORKSPACE + f"srk0_{KEY_TYPE}.pub"
%! nxpcrypto $VERBOSITY key generate -k $KEY_TYPE -o $ROTK_PRIVATE_KEY_PATH --force
# verify that keys were generated
assert os.path.exists(ROTK_PRIVATE_KEY_PATH)
assert os.path.exists(ROTK_PUBLIC_KEY_PATH)
# check that the keys match
%! nxpcrypto $VERBOSITY key verify -k1 $ROTK_PRIVATE_KEY_PATH -k2 $ROTK_PUBLIC_KEY_PATH
nxpcrypto -v key generate -k secp256r1 -o workspace/srk0_secp256r1.pem --force
The key pair has been created: workspace/srk0_secp256r1.pub, workspace/srk0_secp256r1.pem
nxpcrypto -v key verify -k1 workspace/srk0_secp256r1.pem -k2 workspace/srk0_secp256r1.pub
Keys match.
2.2 Generating Keys with nxpcrypto API#
The spsdk.crypto.keys
module handles key operations in the SPSDK. It provides two base classes, PrivateKey
and PublicKey
, which serve as the foundation for working with various types of keys.SPSDK supports all standard keys supported in cryptography like RSA and ECC with PEM and DER formats. In addition to PEM and DER encoding, SPSDK defines NXP encoding that is used with the NXP devices that are memory constrained.
Private Key
The PrivateKey
class is a fundamental component of the SPSDK, acting as an abstract base class for private keys. It inherits from the BaseClass
and includes abstract methods that must be implemented by any subclasses.
Public Key
Similarly, the PublicKey
class is a crucial part of the SPSDK, functioning as an abstract base class for public keys. Like the PrivateKey
class, it extends the BaseClass
and defines abstract methods that its subclasses must implement.
from spsdk.crypto.keys import EccCurve, PrivateKeyEcc, PrivateKeyRsa
# Let's start with RSA key pair
RSA_PRIVATE_KEY_PATH = WORKSPACE + f"rsa_2048.pem"
RSA_PUBLIC_KEY_PATH = WORKSPACE + f"rsa_2048.pub"
priv_key_2048 = PrivateKeyRsa.generate_key(key_size=2048)
pub_key_2048 = priv_key_2048.get_public_key()
# Generate and save rsa keys (size 2048) - pem format
priv_key_2048.save(RSA_PRIVATE_KEY_PATH)
pub_key_2048.save(RSA_PUBLIC_KEY_PATH)
# verify that keys were generated
assert os.path.exists(RSA_PRIVATE_KEY_PATH)
assert os.path.exists(RSA_PUBLIC_KEY_PATH)
match = priv_key_2048.verify_public_key(pub_key_2048)
assert match, "Private key does not match the public key"
print(f"The RSA key pair was generated {RSA_PRIVATE_KEY_PATH}, {RSA_PUBLIC_KEY_PATH}.")
The RSA key pair was generated workspace/rsa_2048.pem, workspace/rsa_2048.pub.
# Now, let's generate ECC key pair
ECC_PRIVATE_KEY_PATH = WORKSPACE + f"ecc_p256.pem"
ECC_PUBLIC_KEY_PATH = WORKSPACE + f"ecc_p256.pub"
priv_key_p256 = PrivateKeyEcc.generate_key(curve_name=EccCurve.SECP256R1)
pub_key_p256 = priv_key_p256.get_public_key()
priv_key_p256.save(ECC_PRIVATE_KEY_PATH)
pub_key_p256.save(ECC_PUBLIC_KEY_PATH)
# verify that keys were generated
assert os.path.exists(ECC_PRIVATE_KEY_PATH)
assert os.path.exists(ECC_PUBLIC_KEY_PATH)
match = priv_key_p256.verify_public_key(pub_key_p256)
assert match, "Private key does not match the public key"
print(f"The ECC key pair was generated {ECC_PRIVATE_KEY_PATH}, {ECC_PUBLIC_KEY_PATH}.")
The ECC key pair was generated workspace/ecc_p256.pem, workspace/ecc_p256.pub.