|
1 | 1 | using System; |
2 | 2 | using System.Collections.Concurrent; |
3 | 3 | using System.Collections.Generic; |
| 4 | +using System.Formats.Asn1; |
4 | 5 | using System.Net.Http; |
5 | 6 | using System.Net.Http.Headers; |
6 | 7 | using System.Security.Cryptography; |
@@ -131,16 +132,31 @@ private string CreateJwtToken() |
131 | 132 | var unsignedJwtData = $"{headerBase64}.{payloadBase64}"; |
132 | 133 | var unsignedJwtBytes = Encoding.UTF8.GetBytes(unsignedJwtData); |
133 | 134 |
|
134 | | - var privateKeyBytes = Convert.FromBase64String(CryptoHelper.CleanP8Key(settings.P8PrivateKey)); |
| 135 | + var pkcs8Bytes = Convert.FromBase64String(CryptoHelper.CleanP8Key(settings.P8PrivateKey)); |
| 136 | + var ecPrivateKey = ExtractEcPrivateKey(pkcs8Bytes); |
135 | 137 |
|
136 | 138 | using var dsa = ECDsa.Create(); |
137 | | - dsa.ImportPkcs8PrivateKey(privateKeyBytes, out _); |
| 139 | + dsa.ImportECPrivateKey(ecPrivateKey, out _); |
138 | 140 |
|
139 | 141 | var signature = dsa.SignData(unsignedJwtBytes, HashAlgorithmName.SHA256); |
140 | 142 | var signatureBase64 = Base64UrlEncode(signature); |
141 | 143 | return $"{unsignedJwtData}.{signatureBase64}"; |
142 | 144 | } |
143 | 145 |
|
| 146 | + /// <summary> |
| 147 | + /// Extracts the inner EC private key (SEC 1 / RFC 5915) from a PKCS#8 envelope. |
| 148 | + /// Using ImportECPrivateKey instead of ImportPkcs8PrivateKey avoids the CNG PKCS#8 import |
| 149 | + /// path which fails on Windows Server/IIS when "Load User Profile" is disabled. |
| 150 | + /// </summary> |
| 151 | + internal static byte[] ExtractEcPrivateKey(byte[] pkcs8PrivateKey) |
| 152 | + { |
| 153 | + var reader = new AsnReader(pkcs8PrivateKey, AsnEncodingRules.DER); |
| 154 | + var pkcs8 = reader.ReadSequence(); |
| 155 | + pkcs8.ReadEncodedValue(); // version |
| 156 | + pkcs8.ReadSequence(); // algorithm identifier |
| 157 | + return pkcs8.ReadOctetString(); // SEC 1 EC private key |
| 158 | + } |
| 159 | + |
144 | 160 | private static string Base64UrlEncode(string str) |
145 | 161 | { |
146 | 162 | var bytes = Encoding.UTF8.GetBytes(str); |
|
0 commit comments