Table of Contents

Class AuthenticateSignCommand

Namespace
Yubico.YubiKey.Piv.Commands
Assembly
Yubico.YubiKey.dll

Build a digital signature using the private key in one of the PIV slots.

public sealed class AuthenticateSignCommand : AuthenticateCommand, IYubiKeyCommand<AuthenticateSignResponse>
Inheritance
object
AuthenticateSignCommand
Implements
Inherited Members

Remarks

In the PIV standard, there is a command called GENERAL AUTHENTICATE. Although it is one command, it can do four things: authenticate a management key (challenge-response), sign arbitrary data, RSA decryption, and EC Diffie-Hellman. The SDK breaks these four operations into separate classes. This class is how you perform "GENERAL AUTHENTICATE: Sign".

The partner Response class is AuthenticateSignResponse.

In order to create a signature, it is possible you must verify the PIN. The PIN is not part of this command. For information on how to verify a PIN in order to perform operations, see the User's Manual entry on PIV commands access control.

The caller supplies the slot to use. Slot 9C is the "digital signature" slot, but any PIV slot that holds a private key, other then F9, will be able to create a signature. That is, any PIV slot other than 80, 81, 9B, or F9 will be able to sign. Note that slot F9 contains the attestation key, which will sign a certificate it creates, so it can sign. It simply cannot sign arbitrary data, only attestation statements.

The caller also supplies the digest of the data to sign. For RSA signatures, the digest must be formatted following PKCS 1 version 1.5, or PKCS 1 PSS (Probabilistic Signature Scheme). See RFC 8017 for details on these formats. For ECC signatures, the digest provided is not formatted further. For example, if you digest the data to sign using SHA-256, the digest is 32 bytes and you provide 32 bytes to this command. See also the User's Manual entry on signing in the PIV commands page.

If the key is ECC-P256, the digest must be 256 bits (32 bytes). If the key is ECC-P384, the digest must be 384 bits (48 bytes).

You should know which algorithm (and size) the key in the requested slot is, because if you provide the wrong format (or size) of digest, the YubiKey will return an error.

This class will copy a reference to the digest data, so you should not clear or alter that input data until this class is done with it, which is after the call to SendCommand.

Example:

/* This example assumes there is some code that will digest the data. */
byte[] sha384Digest = DigestDataToSign(SHA384, dataToSign);
IYubiKeyConnection connection = key.Connect(YubiKeyApplication.Piv);
var signCommand = new AuthenticateSignCommand(sha384Digest, PivSlot.Signing);
AuthenticateSignResponse signResponse = connection.SendCommand(signCommand);
if (signResponse.Status != ResponseStatus.Success)
{
  // handle error
}
byte[] signature = signResponse.GetData();

Constructors

AuthenticateSignCommand(ReadOnlyMemory<byte>, byte)

Initializes a new instance of the AuthenticateSignCommand class. This command takes the slot number and the (possibly formatted) digest of the data to sign.

public AuthenticateSignCommand(ReadOnlyMemory<byte> digestData, byte slotNumber)

Parameters

digestData ReadOnlyMemory<byte>

The message digest of the data to sign, formatted, if RSA.

slotNumber byte

The slot holding the private key to use.

Remarks

The slot number must be for a slot that holds an asymmetric key and can perform arbitrary signing, which is all asymmetric key slots other than F9. See the User's Manual entry on PIV slots , entry on signing , and PivSlot.

The digest data is formatted if RSA. If the key that will be used to sign is RSA-1024, the the digest data must be 128 (1024 bits) bytes long. If the key is RSA-2048, then the digest data must be 256 bytes (2048 bits) long. If the key is RSA-3072, then the digest data must be 384 bytes (3072 bits) long. If the key is RSA-4096, then the digest data must be 512 bytes (4096 bits) long. See also the User's Manual entry on signing in the PIV commands page.

For ECC, the digest data is not formatted, it is simply the output of the message digest algorithm. If the key that will be used to sign is ECC-P256, then the digest data must be 32 bytes (256 bits) long. You will likely use SHA-256, which is the algorithm specified in the PIV standard. If the key is ECC-P384, then the digest data must be 48 bytes (384 bits) long. You will likely use SHA-384, which is the algorithm specified in the PIV standard.

Note that if the result of the digest has leading 00 bytes, you leave those bytes in the digestData. For example:

If the result of the SHA-256 digest is
  00 00 87 A9 31 ... 7C
then you pass in 32 bytes:
  00 00 87 A9 31 ... 7C
Do not strip the leading 00 bytes and pass in only 30 bytes (87 A9 ... 7C).

If you are signing with ECC and you use a digest algorithm that produces smaller output (not recommended, but if you do), prepend 00 bytes to make sure the length of data passed in is the correct length.

Exceptions

ArgumentException

The data to sign (formatted digest) is not the correct length.

AuthenticateSignCommand(ReadOnlyMemory<byte>, byte, PivAlgorithm)

Initializes a new instance of the AuthenticateSignCommand class. This command takes the slot number and the (possibly formatted) digest of the data to sign.

public AuthenticateSignCommand(ReadOnlyMemory<byte> digestData, byte slotNumber, PivAlgorithm algorithm)

Parameters

digestData ReadOnlyMemory<byte>

The message digest of the data to sign, formatted, if RSA.

slotNumber byte

The slot holding the private key to use.

algorithm PivAlgorithm

The algorithm of the key to use.

Remarks

The slot number must be for a slot that holds an asymmetric key and can perform arbitrary signing, which is all asymmetric key slots other than F9. See the User's Manual entry on PIV slots , entry on signing , and PivSlot.

The digest data is formatted if RSA. If the key that will be used to sign is RSA-1024, the digest data must be 128 (1024 bits) bytes long. If the key is RSA-2048, then the digest data must be 256 bytes (2048 bits) long. If the key is RSA-3072, then the digest data must be 384 bytes (3072 bits) long. If the key is RSA-4096, then the digest data must be 512 bytes (4096 bits) long. See also the User's Manual entry on signing in the PIV commands page.

For ECC, the digest data is not formatted, it is simply the output of the message digest algorithm. If the key that will be used to sign is ECC-P256, then the digest data must be 32 bytes (256 bits) long. You will likely use SHA-256, which is the algorithm specified in the PIV standard. If the key is ECC-P384, then the digest data must be 48 bytes (384 bits) long. You will likely use SHA-384, which is the algorithm specified in the PIV standard.

Note that if the result of the digest has leading 00 bytes, you leave those bytes in the digestData. For example:

If the result of the SHA-256 digest is
  00 00 87 A9 31 ... 7C
then you pass in 32 bytes:
  00 00 87 A9 31 ... 7C
Do not strip the leading 00 bytes and pass in only 30 bytes (87 A9 ... 7C).

If you are signing with ECC and you use a digest algorithm that produces smaller output (not recommended, but if you do), prepend 00 bytes to make sure the length of data passed in is the correct length.

Exceptions

ArgumentException

The data to sign (formatted digest) is not the correct length.

Methods

CreateResponseForApdu(ResponseApdu)

Creates the corresponding IYubiKeyResponse implementation for the current command.

public AuthenticateSignResponse CreateResponseForApdu(ResponseApdu responseApdu)

Parameters

responseApdu ResponseApdu

The ResponseApdu returned by the YubiKey.

Returns

AuthenticateSignResponse

The implementation of IYubiKeyResponse that parses and presents ths response APDU.