You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows更新后KeyInfo加载失败,求无需修改注册表的解决方案

解决Windows更新后KeyInfo加载的"Malformed element keyinfo"异常

我之前也碰到过一模一样的问题——Windows某次更新后,.NET的EncryptedKey.LoadXml()突然对KeyInfo节点的属性校验变严格了,带xsi:type="KeyInfoType"的节点直接抛出SecurityException。下面给你几个不用改注册表、也不用手动删属性的可行方案:

方案1:自定义SignedXml绕过KeyInfo校验

你可以继承SignedXml类,重写它读取KeyInfo的方法,临时关闭XML的校验规则,这样就能跳过对xsi:type属性的检查。代码示例如下:

public class RelaxedSignedXml : SignedXml
{
    public RelaxedSignedXml(XmlDocument doc) : base(doc) { }
    public RelaxedSignedXml(XmlElement elem) : base(elem) { }

    protected override KeyInfo ReadKeyInfo(XmlReader reader)
    {
        // 保存原始读取器设置,创建一个禁用校验的新设置
        var originalSettings = reader.Settings;
        var relaxedSettings = new XmlReaderSettings
        {
            ValidationType = ValidationType.None,
            IgnoreWhitespace = originalSettings?.IgnoreWhitespace ?? true,
            IgnoreComments = originalSettings?.IgnoreComments ?? true
        };

        // 用宽松设置的读取器读取KeyInfo
        using var relaxedReader = XmlReader.Create(reader, relaxedSettings);
        relaxedReader.MoveToContent();
        return base.ReadKeyInfo(relaxedReader);
    }
}

之后你可以用这个自定义类来处理加密/签名操作,或者配合EncryptedKey使用,就能正常加载带xsi:type属性的KeyInfo节点了。

方案2:用包装XmlReader过滤冗余属性

如果你不想修改SignedXml的逻辑,可以创建一个包装类的XmlReader,在读取KeyInfo节点时自动过滤掉xsi:type属性,不用修改原始XML字符串:

public class KeyInfoCleanupReader : XmlReader
{
    private readonly XmlReader _innerReader;
    private List<XmlAttribute> _filteredAttributes;
    private bool _isKeyInfoElement;

    public KeyInfoCleanupReader(XmlReader innerReader)
    {
        _innerReader = innerReader;
    }

    // 重写核心读取逻辑
    public override bool Read()
    {
        bool result = _innerReader.Read();
        if (result && _innerReader.NodeType == XmlNodeType.Element 
            && _innerReader.LocalName == "KeyInfo" 
            && _innerReader.NamespaceURI == "http://www.w3.org/2000/09/xmldsig#")
        {
            _isKeyInfoElement = true;
            // 过滤掉xsi:type属性
            _filteredAttributes = new List<XmlAttribute>();
            for (int i = 0; i < _innerReader.AttributeCount; i++)
            {
                _innerReader.MoveToAttribute(i);
                if (!(_innerReader.NamespaceURI == "http://www.w3.org/2001/XMLSchema-instance" 
                     && _innerReader.LocalName == "type"))
                {
                    var attr = (XmlAttribute)_innerReader.ReadOuterXml();
                    _filteredAttributes.Add(attr);
                }
            }
            _innerReader.MoveToElement();
        }
        else
        {
            _isKeyInfoElement = false;
        }
        return result;
    }

    // 重写属性相关方法,返回过滤后的结果
    public override int AttributeCount => _isKeyInfoElement ? _filteredAttributes.Count : _innerReader.AttributeCount;

    public override string GetAttribute(int i)
    {
        return _isKeyInfoElement ? _filteredAttributes[i].Value : _innerReader.GetAttribute(i);
    }

    // 补充重写其他必要的XmlReader抽象方法
    public override XmlNodeType NodeType => _innerReader.NodeType;
    public override string LocalName => _innerReader.LocalName;
    public override string NamespaceURI => _innerReader.NamespaceURI;
    public override bool EOF => _innerReader.EOF;
    public override string Value => _innerReader.Value;
    // 其他方法按需补充...
}

使用的时候,用这个包装后的读取器加载XML:

var xmlDoc = new XmlDocument();
using var stringReader = new StringReader(rawData);
using var originalReader = XmlReader.Create(stringReader);
using var cleanedReader = new KeyInfoCleanupReader(originalReader);
xmlDoc.Load(cleanedReader);

var encryptedKey = new EncryptedKey();
encryptedKey.LoadXml(xmlDoc.DocumentElement);

关于Windows更新的原因

目前微软官方没有针对这个变更的明确公开说明,但推测是某次.NET Framework的安全更新收紧了XML数字签名相关节点的Schema校验规则——xsi:type="KeyInfoType"属于冗余属性(KeyInfo本身就是这个类型),之前的版本允许这种冗余,更新后被判定为格式错误。你可以查看近期的.NET Framework安全更新公告,可能会找到相关的变更细节。

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:44:07