调用GetMetadata读取YubiKey插槽元数据时遇“未找到引用数据”异常
解决YubiKey PIV GetMetadata抛出"Referenced data or reference data no found"异常的问题
问题原因
这个异常的核心原因是目标PIV插槽中未存储密钥或证书。YubiKey的PIV元数据是与插槽内的密钥/证书绑定的,空插槽没有可读取的元数据,调用GetMetadata就会触发该错误。
即使PIN和管理密钥验证成功,只要插槽未初始化(未写入密钥/证书),就会出现这个问题。尤其是PivSlot.Attestation(F9插槽),默认状态下是空的,除非你主动生成了attestation密钥。
解决方案
你可以通过两种方式解决这个问题:给每个插槽的元数据读取操作单独处理异常,或者先检查插槽是否有密钥存在再读取元数据。
方案1:逐个捕获空插槽异常
修改GetCurrentSlotStatus方法,对每个插槽的读取操作单独捕获异常,跳过空插槽的报错:
public void GetCurrentSlotStatus() { if( _device == null) { Console.WriteLine("No Yubikey selected, cannot get slot status."); return; } try { Console.WriteLine("Attempting to read slot status..."); PivSession pivSession = new PivSession(_device); Console.WriteLine("Establishing session..."); if (CreateSessionWithYubikey(pivSession) != true) { Console.WriteLine("Failed to create session with device."); return; } if (_device.FirmwareVersion >= new FirmwareVersion(5, 3, 0)) { Console.WriteLine("Reading slot data..."); // 处理Authentication插槽(9A) try { PivMetadata metadataSlot9A = pivSession.GetMetadata(PivSlot.Authentication); Console.WriteLine("Authentication Slot: " + metadataSlot9A.ToString()); } catch (Exception ex) { Console.WriteLine("Authentication Slot: 未初始化或无元数据 - " + ex.Message); } // 处理Signing插槽(9C) try { PivMetadata metadataSlot9C = pivSession.GetMetadata(PivSlot.Signing); Console.WriteLine("Signing Slot: " + metadataSlot9C.ToString()); } catch (Exception ex) { Console.WriteLine("Signing Slot: 未初始化或无元数据 - " + ex.Message); } // 处理Key Management插槽(9D) try { PivMetadata metadataSlot9D = pivSession.GetMetadata(PivSlot.KeyManagement); Console.WriteLine("Key Management Slot: " + metadataSlot9D.ToString()); } catch (Exception ex) { Console.WriteLine("Key Management Slot: 未初始化或无元数据 - " + ex.Message); } // 处理Card Authentication插槽(9E) try { PivMetadata metadataSlot9E = pivSession.GetMetadata(PivSlot.CardAuthentication); Console.WriteLine("Card Authentication Slot: " + metadataSlot9E.ToString()); } catch (Exception ex) { Console.WriteLine("Card Authentication Slot: 未初始化或无元数据 - " + ex.Message); } // 处理Attestation插槽(F9) try { PivMetadata metadataSlotF9 = pivSession.GetMetadata(PivSlot.Attestation); Console.WriteLine("Attestation Slot: " + metadataSlotF9.ToString()); } catch (Exception ex) { Console.WriteLine("Attestation Slot: 未初始化或无元数据 - " + ex.Message); } } else { Console.WriteLine("Firmware version does not support metadata retrieval."); } } catch(Exception e) { Console.WriteLine("全局错误: " + e.Message); return; } }
方案2:先检查插槽是否有密钥
在调用GetMetadata前,通过TryGetPublicKey检查插槽是否存在密钥,避免触发异常:
// 以Authentication插槽为例 if (pivSession.TryGetPublicKey(PivSlot.Authentication, out var publicKey)) { var metadata = pivSession.GetMetadata(PivSlot.Authentication); Console.WriteLine("Authentication Slot: " + metadata.ToString()); } else { Console.WriteLine("Authentication Slot: 无密钥"); }
额外提示
- 新出厂的YubiKey所有PIV插槽默认都是空的,只有写入密钥或证书后才会生成元数据。
PivSlot.Attestation插槽需要手动调用pivSession.GenerateAttestationKey生成密钥后,才会有可读取的元数据。
内容的提问来源于stack exchange,提问作者user32276102
相关产品推荐
相关产品推荐

