@@ -322,7 +322,7 @@ public KeyCredential(byte[] publicKey, Guid? deviceId, string owner, DateTime? c
322322
323323 private void Initialize ( byte [ ] publicKey , Guid ? deviceId , string owner , DateTime ? currentTime , bool isComputerKey )
324324 {
325- // Prodess owner DN/UPN
325+ // Process owner DN/UPN
326326 ArgumentException . ThrowIfNullOrEmpty ( owner ) ;
327327 this . Owner = owner ;
328328
@@ -333,15 +333,27 @@ private void Initialize(byte[] publicKey, Guid? deviceId, string owner, DateTime
333333 this . RawKeyMaterial = publicKey ;
334334 this . Usage = KeyUsage . NGC ;
335335 this . Source = KeySource . AD ;
336- this . DeviceId = deviceId ;
337336
338- // Computer NGC keys have to meet some requirements to pass the validated write
339- // The CustomKeyInformation entry is not present.
340- // The KeyApproximateLastLogonTimeStamp entry is not present.
341- if ( ! isComputerKey )
337+ if ( isComputerKey )
338+ {
339+ // Computer NGC keys have to meet some requirements to pass the validated write.
340+ // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/f70afbcc-780e-4d91-850c-cfadce5bb15c
341+ // The KeyApproximateLastLogonTimeStamp entry must not present.
342+ // Although the spec also says that the CustomKeyInformation entry must not present,
343+ // in practice it seems that Windows adds it with KeyFlags.MFANotUsed.
344+ this . CustomKeyInfo = new CustomKeyInformation ( KeyFlags . MFANotUsed ) ;
345+
346+ if ( deviceId . HasValue )
347+ {
348+ throw new ArgumentException ( "Device ID cannot be specified for computer NGC keys." , nameof ( deviceId ) ) ;
349+ }
350+ }
351+ else
342352 {
343353 this . LastLogonTime = this . CreationTime ;
344354 this . CustomKeyInfo = new CustomKeyInformation ( KeyFlags . None ) ;
355+ // Device ID is only used for user NGC keys, but not for computer NGC keys.
356+ this . DeviceId = deviceId ;
345357 }
346358 }
347359
0 commit comments