Skip to content

Commit 12243ab

Browse files
committed
rest of public key info, formatting changes
1 parent 4029647 commit 12243ab

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

docs/users-manual/application-piv/private-keys.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ IPrivateKey privateKey = RSAPrivateKey.CreateFromPkcs8(pkcs8Bytes); // or ECPriv
187187
188188
To build a PrivateKey when importing from PEM, you will need to first determine the private key algorithm. Once you know the algorithm, you can use the appropriate C# class to read the encoded data (for example, ``RSAPrivateKey``, ``ECPrivateKey``, or ``Curve25519PrivateKey`` ).
189189
190-
The algorithm is specified in the key data itself. However, the .NET Base Class Library does not have a class that can parse ``PrivateKeyInfo`` and build the appropriate object. The only methods that can read this encoding are in classes for the specific algorithms. That is, the RSA class can read PrivateKeyInfo only if the input data is an RSA key, the ECDsa class can read it only if the input data is an ECC key, etc.
190+
The algorithm is specified in the key data itself. However, the .NET Base Class Library does not have a class that can parse ``PrivateKeyInfo`` and build the appropriate object. The only methods that can read this encoding are in classes for the specific algorithms. That is, the RSA class can read ``PrivateKeyInfo`` only if the input data is an RSA key, the ECDsa class can read it only if the input data is an ECC key, etc.
191191
192192
One possible workaround would be to supply the encoded key to the RSA class and if it works, we have an RSA key. If it does not work, give the encoded key to the ECDsa class. However, if the RSA class gets an encoded key that is not RSA, it throws an exception, and using exceptions to determine code flow is not best practice.
193193
@@ -214,7 +214,7 @@ AlgorithmIdentifier ::= SEQUENCE {
214214
This means that the DER encoding will look something like the following:
215215

216216
```csharp
217-
30 len // the len octets might be one, two, or three bytes long.
217+
30 len // The len octets might be one, two, or three bytes long.
218218
02 01 00
219219
30 len
220220
06 len

docs/users-manual/application-piv/public-keys.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ Curve25519PublicKey x25519Key = Curve25519PublicKey.CreateFromValue(publicPoint,
102102

103103
## Generating key pairs
104104

105+
When you generate a new key pair in a YubiKey's PIV application, you are given the public key, which is returned as an instance of the ``PublicKey`` class. From this class, you can obtain important information about the key, including ``KeyDefinition`` and ``KeyType``. Depending on the specific class, ``Parameters`` (EC and RSA) and ``PublicPoint`` (EC and Curve25519) are also included.
106+
105107
```csharp
106108
using var pivSession = new PivSession(yubiKey);
107109
pivSession.KeyCollector = yourKeyCollector;
@@ -167,6 +169,54 @@ byte[] spkiBytes = Convert.FromBase64String(base64Data);
167169
IPublicKey publicKey = RSAPublicKey.CreateFromSubjectPublicKeyInfo(spkiBytes); // or ECPublicKey, etc.
168170
```
169171

172+
> [!NOTE]
173+
> When importing a public key in PEM format, there are a number of possible header and footer combinations, including the following:
174+
>
175+
> ```
176+
> -----BEGIN PUBLIC KEY-----
177+
> -----END PUBLIC KEY-----
178+
>
179+
> -----BEGIN RSA PUBLIC KEY-----
180+
> -----END RSA PUBLIC KEY-----
181+
>
182+
> -----BEGIN EC PUBLIC KEY-----
183+
> -----END EC PUBLIC KEY-----
184+
> ```
185+
186+
### Determining the algorithm when importing a public key in PEM format
187+
188+
If you have a byte array that contains the ``SubjectPublicKeyInfo``, and you want to build a ``PublicKey``, you will need to first determine the public key algorithm. Once you know the algorithm, you can use the appropriate C# class to read the encoded data (for example, ``RSAPublicKey``, ``ECPublicKey``, or ``Curve25519PublicKey`` ).
189+
190+
The algorithm is specified in the key data itself. However, the .NET Base Class Library does not have a class that can parse ``SubjectPublicKeyInfo`` and build the appropriate object. The only methods that can read this encoding are in classes for the specific algorithms. That is, the RSA class can read ``SubjectPublicKeyInfo`` only if the input data is an RSA key, the ECDsa class can read it only if the input data is an ECC key, etc.
191+
192+
One possible workaround would be to supply the encoded key to the RSA class and if it works, we have an RSA key. If it does not work, give the encoded key to the ECDsa class. However, if the RSA class gets an encoded key that is not RSA, it throws an exception, and using exceptions to determine code flow is not best practice.
193+
194+
To determine the algorithm of an imported key, we need to open up the encoding and read the object identifier (OID) of the ``AlgorithmIdentifier``. And to find the OID, we need to decode the DER encoding of ``SubjectPublicKeyInfo``.
195+
196+
``SubjectPublicKeyInfo`` is defined as:
197+
198+
```csharp
199+
SubjectPublicKeyInfo ::= SEQUENCE {
200+
algorithm AlgorithmIdentifier,
201+
subjectPublicKey BIT STRING }
202+
203+
AlgorithmIdentifier ::= SEQUENCE {
204+
algorithm OBJECT IDENTIFIER,
205+
parameter ANY DEFINED BY algorithm OPTIONAL }
206+
```
207+
208+
This means that the DER encoding will look something like the following:
209+
210+
```csharp
211+
30 len // The len octets might be one, two, or three bytes long.
212+
30 len
213+
06 len
214+
OID bytes
215+
etc.
216+
```
217+
218+
To get to the OID, we need to read the first ``30 len``, then the second ``30 len``, then the ``06 len``.
219+
170220
## Error handling
171221

172222
Factory methods validate input and may throw exceptions:

0 commit comments

Comments
 (0)