Javascript chrome extension表示安装时缺少CRX\u所需的\u-PROOF\u

Javascript chrome extension表示安装时缺少CRX\u所需的\u-PROOF\u,javascript,google-chrome,google-chrome-extension,Javascript,Google Chrome,Google Chrome Extension,您好,我刚刚创建了一个公司内部使用的chrome扩展,我不想发布它,并想在我将该扩展打包到本地chrome中后传递给我的同事。它给了我一个错误,说CRX\u REQUIRED\u PROOF\u MISSING我对这个错误了解不够,请在这个问题上帮助我。 您无法分发不在Chrome扩展商店中的扩展插件。 根据官方的chrome文档,从chrome扩展商店或其外部分发的每个扩展都必须上传到chrome扩展商店。 如果你想在商店外分发你的扩展,在你上传它之后,我认为你应该创建一个脚本,它会为你安装它

您好,我刚刚创建了一个公司内部使用的chrome扩展,我不想发布它,并想在我将该扩展打包到本地chrome中后传递给我的同事。它给了我一个错误,说
CRX\u REQUIRED\u PROOF\u MISSING
我对这个错误了解不够,请在这个问题上帮助我。

您无法分发不在Chrome扩展商店中的扩展插件。 根据官方的chrome文档,从chrome扩展商店或其外部分发的每个扩展都必须上传到chrome扩展商店。
如果你想在商店外分发你的扩展,在你上传它之后,我认为你应该创建一个脚本,它会为你安装它。

你需要修改你的本地策略,允许从你需要指定的自定义URL库进行安装。此信息保存在Linux上的JSON或Windows上的注册表中。请在此处查看此链接,然后单击以了解如何将扩展的URL列入白名单。然后使用启用特定的扩展ID

另外,要获得稳定的扩展ID,请使用Chrome打包器,这意味着使用命令行执行Chrome--pack extension=“path\to\extension\folder”-pack extension key=“path\to\file.pem”。只要.pem被重用,这将生成一个适当的.crx,它具有一个稳定的ID,您可以将其列入白名单,并在更新时保持不变

要从.CRX读取ID,这是我的C#代码:

private静态字符串ReadExtensionIdFromCrx3(字符串路径)
{
使用var stream=File.Open(路径,FileMode.Open,FileAccess.Read,FileShare.Read);
从CRX3(流)返回ReadExtensionIdFromCrx3;
}
私有静态字符串ReadExtensionIdFromCrx3(流)
{
使用var reader=newbinaryreader(流);
使用var netreader=newbinarydreadernetorder(流);
var magic=netreader.ReadInt32();
如果(魔法!=0x43723234)
{
抛出新的InvalidDataException();
}
var version=netreader.ReadInt32();
如果(版本!=0x03000000)
{
抛出新的InvalidDataException();
}
var headerSize=reader.ReadInt32();
var headerBytes=reader.ReadBytes(headerSize);
var header=CrxFileHeader.Parser.ParseFrom(headerBytes);
var first=头文件.Sha256WithRsa[0];
var halfHashed=新字节[16];
使用(var hash=SHA256.Create())
{
var hashed=hash.ComputeHash(first.PublicKey.ToByteArray());
Copy(散列,0,半散列,0,半散列,长度);
}
var sb=新的StringBuilder();
for(int it=0;it
你也可以使用这个极简的网络订单

public class BinaryReaderNetOrder : BinaryReader
{
    public BinaryReaderNetOrder(Stream stream) : base(stream) { }

    public override short ReadInt16()
    {
        return BitConverter.ToInt16(ReadNetOrder(2), 0);
    }

    public override int ReadInt32()
    {
        return BitConverter.ToInt32(ReadNetOrder(4), 0);
    }

    public override long ReadInt64()
    {
        return BitConverter.ToInt64(ReadNetOrder(8), 0);
    }

    public override ushort ReadUInt16()
    {
        return BitConverter.ToUInt16(ReadNetOrder(2), 0);
    }

    public override uint ReadUInt32()
    {
        return BitConverter.ToUInt32(ReadNetOrder(4), 0);
    }

    public override ulong ReadUInt64()
    {
        return BitConverter.ToUInt64(ReadNetOrder(8), 0);
    }

    public override float ReadSingle()
    {
        return BitConverter.ToSingle(ReadNetOrder(4), 0);
    }

    public override double ReadDouble()
    {
        return BitConverter.ToDouble(ReadNetOrder(8), 0);
    }

    public override byte[] ReadBytes(int count)
    {
        var data = base.ReadBytes(count);
        if (data.Length < count)
        {
            throw new EndOfStreamException();
        }
        if (data.Length > count)
        {
            throw new IOException();
        }
        return data;
    }

    private byte[] ReadNetOrder(int count)
    {
        if (count < 2 || count > 8)
        {
            throw new ArgumentOutOfRangeException(nameof(count));
        }

        var data = ReadBytes(count);
        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(data);
        }
        return data;
    }
}
公共类BinaryReaderNoder:BinaryReader
{
公共二进制读取器(流):基(流){}
公共覆盖短ReadInt16()
{
返回BitConverter.ToInt16(ReadNetOrder(2),0);
}
公共覆盖int ReadInt32()
{
返回BitConverter.ToInt32(ReadNetOrder(4),0);
}
公共重写长ReadInt64()
{
返回BitConverter.ToInt64(ReadNetOrder(8),0);
}
公共覆盖ushort ReadUInt16()
{
返回BitConverter.ToUInt16(ReadNetOrder(2),0);
}
公共覆盖uint ReadUInt32()
{
返回BitConverter.ToUInt32(ReadNetOrder(4),0);
}
公共覆盖ulong ReadUInt64()
{
返回BitConverter.ToUInt64(ReadNetOrder(8),0);
}
公共覆盖float ReadSingle()
{
返回BitConverter.ToSingle(ReadNetOrder(4),0);
}
公共重写双ReadDouble()
{
返回BitConverter.ToDouble(ReadNetOrder(8),0);
}
公共重写字节[]读取字节(整数计数)
{
var data=base.ReadBytes(计数);
如果(数据长度<计数)
{
抛出新的EndOfStreamException();
}
如果(data.Length>count)
{
抛出新IOException();
}
返回数据;
}
专用字节[]ReadNetOrder(整数计数)
{
如果(计数<2 | |计数>8)
{
抛出新ArgumentOutOfRangeException(nameof(count));
}
var数据=读取字节(计数);
if(位转换器.IsLittleEndian)
{
数组。反向(数据);
}
返回数据;
}
}
您还需要Protobuf头定义:

// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: test.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code

using pb = Google.Protobuf;
using pbc = Google.Protobuf.Collections;
using pbr = Google.Protobuf.Reflection;
using scg = System.Collections.Generic;
/// <summary>Holder for reflection information generated from test.proto</summary>
public static partial class TestReflection
{

    #region Descriptor
    /// <summary>File descriptor for test.proto</summary>
    public static pbr::FileDescriptor Descriptor
    {
        get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static TestReflection()
    {
        byte[] descriptorData = System.Convert.FromBase64String(
            string.Concat(
              "Cgp0ZXN0LnByb3RvIooBCg1DcnhGaWxlSGVhZGVyEiwKD3NoYTI1Nl93aXRo",
              "X3JzYRgCIAMoCzITLkFzeW1tZXRyaWNLZXlQcm9vZhIuChFzaGEyNTZfd2l0",
              "aF9lY2RzYRgDIAMoCzITLkFzeW1tZXRyaWNLZXlQcm9vZhIbChJzaWduZWRf",
              "aGVhZGVyX2RhdGEYkE4gASgMIjsKEkFzeW1tZXRyaWNLZXlQcm9vZhISCgpw",
              "dWJsaWNfa2V5GAEgASgMEhEKCXNpZ25hdHVyZRgCIAEoDCIcCgpTaWduZWRE",
              "YXRhEg4KBmNyeF9pZBgBIAEoDGIGcHJvdG8z"));
        descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
            new pbr::FileDescriptor[] { },
            new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
      new pbr::GeneratedClrTypeInfo(typeof(CrxFileHeader), CrxFileHeader.Parser, new[]{ "Sha256WithRsa", "Sha256WithEcdsa", "SignedHeaderData" }, null, null, null, null),
      new pbr::GeneratedClrTypeInfo(typeof(AsymmetricKeyProof), AsymmetricKeyProof.Parser, new[]{ "PublicKey", "Signature" }, null, null, null, null),
      new pbr::GeneratedClrTypeInfo(typeof(SignedData), SignedData.Parser, new[]{ "CrxId" }, null, null, null, null)
            }));
    }
    #endregion

}
#region Messages
public sealed partial class CrxFileHeader : pb::IMessage<CrxFileHeader>
{
    private static readonly pb::MessageParser<CrxFileHeader> _parser = new pb::MessageParser<CrxFileHeader>(() => new CrxFileHeader());
    private pb::UnknownFieldSet _unknownFields;
    [DebuggerNonUserCode]
    public static pb::MessageParser<CrxFileHeader> Parser { get { return _parser; } }

    [DebuggerNonUserCode]
    public static pbr::MessageDescriptor Descriptor
    {
        get { return TestReflection.Descriptor.MessageTypes[0]; }
    }

    [DebuggerNonUserCode]
    pbr::MessageDescriptor pb::IMessage.Descriptor
    {
        get { return Descriptor; }
    }

    [DebuggerNonUserCode]
    public CrxFileHeader()
    {
        OnConstruction();
    }

    partial void OnConstruction();

    [DebuggerNonUserCode]
    public CrxFileHeader(CrxFileHeader other) : this()
    {
        sha256WithRsa_ = other.sha256WithRsa_.Clone();
        sha256WithEcdsa_ = other.sha256WithEcdsa_.Clone();
        signedHeaderData_ = other.signedHeaderData_;
        _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [DebuggerNonUserCode]
    public CrxFileHeader Clone()
    {
        return new CrxFileHeader(this);
    }

    /// <summary>Field number for the "sha256_with_rsa" field.</summary>
    public const int Sha256WithRsaFieldNumber = 2;
    private static readonly pb::FieldCodec<AsymmetricKeyProof> _repeated_sha256WithRsa_codec
        = pb::FieldCodec.ForMessage(18, AsymmetricKeyProof.Parser);
    private readonly pbc::RepeatedField<AsymmetricKeyProof> sha256WithRsa_ = new pbc::RepeatedField<AsymmetricKeyProof>();
    /// <summary>
    /// PSS signature with RSA public key. The public key is formatted as a
    /// X.509 SubjectPublicKeyInfo block, as in CRXâ‚‚. In the common case of a
    /// developer key proof, the first 128 bits of the SHA-256 hash of the 
    /// public key must equal the crx_id.
    /// </summary>
    [DebuggerNonUserCode]
    public pbc::RepeatedField<AsymmetricKeyProof> Sha256WithRsa
    {
        get { return sha256WithRsa_; }
    }

    /// <summary>Field number for the "sha256_with_ecdsa" field.</summary>
    public const int Sha256WithEcdsaFieldNumber = 3;
    private static readonly pb::FieldCodec<AsymmetricKeyProof> _repeated_sha256WithEcdsa_codec
        = pb::FieldCodec.ForMessage(26, AsymmetricKeyProof.Parser);
    private readonly pbc::RepeatedField<AsymmetricKeyProof> sha256WithEcdsa_ = new pbc::RepeatedField<AsymmetricKeyProof>();
    /// <summary>
    /// ECDSA signature, using the NIST P-256 curve. Public key appears in
    /// named-curve format.
    /// The pinned algorithm will be this, at least on 2017-01-01.
    /// </summary>
    [DebuggerNonUserCode]
    public pbc::RepeatedField<AsymmetricKeyProof> Sha256WithEcdsa
    {
        get { return sha256WithEcdsa_; }
    }

    /// <summary>Field number for the "signed_header_data" field.</summary>
    public const int SignedHeaderDataFieldNumber = 10000;
    private pb::ByteString signedHeaderData_ = pb::ByteString.Empty;
    /// <summary>
    /// The binary form of a SignedData message. We do not use a nested 
    /// SignedData message, as handlers of this message must verify the proofs
    /// on exactly these bytes, so it is convenient to parse in two steps.
    ///
    /// All proofs in this CrxFile message are on the value
    /// "CRX3 SignedData\x00" + signed_header_size + signed_header_data +
    /// archive, where "\x00" indicates an octet with value 0, "CRX3 SignedData"
    /// is encoded using UTF-8, signed_header_size is the size in octets of the
    /// contents of this field and is encoded using 4 octets in little-endian
    /// order, signed_header_data is exactly the content of this field, and
    /// archive is the remaining contents of the file following the header.
    /// </summary>
    [DebuggerNonUserCode]
    public pb::ByteString SignedHeaderData
    {
        get { return signedHeaderData_; }
        set
        {
            signedHeaderData_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        }
    }

    [DebuggerNonUserCode]
    public override bool Equals(object other)
    {
        return Equals(other as CrxFileHeader);
    }

    [DebuggerNonUserCode]
    public bool Equals(CrxFileHeader other)
    {
        if (ReferenceEquals(other, null))
        {
            return false;
        }
        if (ReferenceEquals(other, this))
        {
            return true;
        }
        if (!sha256WithRsa_.Equals(other.sha256WithRsa_)) return false;
        if (!sha256WithEcdsa_.Equals(other.sha256WithEcdsa_)) return false;
        if (SignedHeaderData != other.SignedHeaderData) return false;
        return Equals(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public override int GetHashCode()
    {
        int hash = 1;
        hash ^= sha256WithRsa_.GetHashCode();
        hash ^= sha256WithEcdsa_.GetHashCode();
        if (SignedHeaderData.Length != 0) hash ^= SignedHeaderData.GetHashCode();
        if (_unknownFields != null)
        {
            hash ^= _unknownFields.GetHashCode();
        }
        return hash;
    }

    [DebuggerNonUserCode]
    public override string ToString()
    {
        return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [DebuggerNonUserCode]
    public void WriteTo(pb::CodedOutputStream output)
    {
        sha256WithRsa_.WriteTo(output, _repeated_sha256WithRsa_codec);
        sha256WithEcdsa_.WriteTo(output, _repeated_sha256WithEcdsa_codec);
        if (SignedHeaderData.Length != 0)
        {
            output.WriteRawTag(130, 241, 4);
            output.WriteBytes(SignedHeaderData);
        }
        if (_unknownFields != null)
        {
            _unknownFields.WriteTo(output);
        }
    }

    [DebuggerNonUserCode]
    public int CalculateSize()
    {
        int size = 0;
        size += sha256WithRsa_.CalculateSize(_repeated_sha256WithRsa_codec);
        size += sha256WithEcdsa_.CalculateSize(_repeated_sha256WithEcdsa_codec);
        if (SignedHeaderData.Length != 0)
        {
            size += 3 + pb::CodedOutputStream.ComputeBytesSize(SignedHeaderData);
        }
        if (_unknownFields != null)
        {
            size += _unknownFields.CalculateSize();
        }
        return size;
    }

    [DebuggerNonUserCode]
    public void MergeFrom(CrxFileHeader other)
    {
        if (other == null)
        {
            return;
        }
        sha256WithRsa_.Add(other.sha256WithRsa_);
        sha256WithEcdsa_.Add(other.sha256WithEcdsa_);
        if (other.SignedHeaderData.Length != 0)
        {
            SignedHeaderData = other.SignedHeaderData;
        }
        _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public void MergeFrom(pb::CodedInputStream input)
    {
        uint tag;
        while ((tag = input.ReadTag()) != 0)
        {
            switch (tag)
            {
                default:
                    _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                    break;
                case 18:
                    {
                        sha256WithRsa_.AddEntriesFrom(input, _repeated_sha256WithRsa_codec);
                        break;
                    }
                case 26:
                    {
                        sha256WithEcdsa_.AddEntriesFrom(input, _repeated_sha256WithEcdsa_codec);
                        break;
                    }
                case 80002:
                    {
                        SignedHeaderData = input.ReadBytes();
                        break;
                    }
            }
        }
    }

}

public sealed partial class AsymmetricKeyProof : pb::IMessage<AsymmetricKeyProof>
{
    private static readonly pb::MessageParser<AsymmetricKeyProof> _parser = new pb::MessageParser<AsymmetricKeyProof>(() => new AsymmetricKeyProof());
    private pb::UnknownFieldSet _unknownFields;
    [DebuggerNonUserCode]
    public static pb::MessageParser<AsymmetricKeyProof> Parser { get { return _parser; } }

    [DebuggerNonUserCode]
    public static pbr::MessageDescriptor Descriptor
    {
        get { return TestReflection.Descriptor.MessageTypes[1]; }
    }

    [DebuggerNonUserCode]
    pbr::MessageDescriptor pb::IMessage.Descriptor
    {
        get { return Descriptor; }
    }

    [DebuggerNonUserCode]
    public AsymmetricKeyProof()
    {
        OnConstruction();
    }

    partial void OnConstruction();

    [DebuggerNonUserCode]
    public AsymmetricKeyProof(AsymmetricKeyProof other) : this()
    {
        publicKey_ = other.publicKey_;
        signature_ = other.signature_;
        _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [DebuggerNonUserCode]
    public AsymmetricKeyProof Clone()
    {
        return new AsymmetricKeyProof(this);
    }

    /// <summary>Field number for the "public_key" field.</summary>
    public const int PublicKeyFieldNumber = 1;
    private pb::ByteString publicKey_ = pb::ByteString.Empty;
    [DebuggerNonUserCode]
    public pb::ByteString PublicKey
    {
        get { return publicKey_; }
        set
        {
            publicKey_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        }
    }

    /// <summary>Field number for the "signature" field.</summary>
    public const int SignatureFieldNumber = 2;
    private pb::ByteString signature_ = pb::ByteString.Empty;
    [DebuggerNonUserCode]
    public pb::ByteString Signature
    {
        get { return signature_; }
        set
        {
            signature_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        }
    }

    [DebuggerNonUserCode]
    public override bool Equals(object other)
    {
        return Equals(other as AsymmetricKeyProof);
    }

    [DebuggerNonUserCode]
    public bool Equals(AsymmetricKeyProof other)
    {
        if (ReferenceEquals(other, null))
        {
            return false;
        }
        if (ReferenceEquals(other, this))
        {
            return true;
        }
        if (PublicKey != other.PublicKey) return false;
        if (Signature != other.Signature) return false;
        return Equals(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public override int GetHashCode()
    {
        int hash = 1;
        if (PublicKey.Length != 0) hash ^= PublicKey.GetHashCode();
        if (Signature.Length != 0) hash ^= Signature.GetHashCode();
        if (_unknownFields != null)
        {
            hash ^= _unknownFields.GetHashCode();
        }
        return hash;
    }

    [DebuggerNonUserCode]
    public override string ToString()
    {
        return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [DebuggerNonUserCode]
    public void WriteTo(pb::CodedOutputStream output)
    {
        if (PublicKey.Length != 0)
        {
            output.WriteRawTag(10);
            output.WriteBytes(PublicKey);
        }
        if (Signature.Length != 0)
        {
            output.WriteRawTag(18);
            output.WriteBytes(Signature);
        }
        if (_unknownFields != null)
        {
            _unknownFields.WriteTo(output);
        }
    }

    [DebuggerNonUserCode]
    public int CalculateSize()
    {
        int size = 0;
        if (PublicKey.Length != 0)
        {
            size += 1 + pb::CodedOutputStream.ComputeBytesSize(PublicKey);
        }
        if (Signature.Length != 0)
        {
            size += 1 + pb::CodedOutputStream.ComputeBytesSize(Signature);
        }
        if (_unknownFields != null)
        {
            size += _unknownFields.CalculateSize();
        }
        return size;
    }

    [DebuggerNonUserCode]
    public void MergeFrom(AsymmetricKeyProof other)
    {
        if (other == null)
        {
            return;
        }
        if (other.PublicKey.Length != 0)
        {
            PublicKey = other.PublicKey;
        }
        if (other.Signature.Length != 0)
        {
            Signature = other.Signature;
        }
        _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public void MergeFrom(pb::CodedInputStream input)
    {
        uint tag;
        while ((tag = input.ReadTag()) != 0)
        {
            switch (tag)
            {
                default:
                    _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                    break;
                case 10:
                    {
                        PublicKey = input.ReadBytes();
                        break;
                    }
                case 18:
                    {
                        Signature = input.ReadBytes();
                        break;
                    }
            }
        }
    }

}

public sealed partial class SignedData : pb::IMessage<SignedData>
{
    private static readonly pb::MessageParser<SignedData> _parser = new pb::MessageParser<SignedData>(() => new SignedData());
    private pb::UnknownFieldSet _unknownFields;
    [DebuggerNonUserCode]
    public static pb::MessageParser<SignedData> Parser { get { return _parser; } }

    [DebuggerNonUserCode]
    public static pbr::MessageDescriptor Descriptor
    {
        get { return TestReflection.Descriptor.MessageTypes[2]; }
    }

    [DebuggerNonUserCode]
    pbr::MessageDescriptor pb::IMessage.Descriptor
    {
        get { return Descriptor; }
    }

    [DebuggerNonUserCode]
    public SignedData()
    {
        OnConstruction();
    }

    partial void OnConstruction();

    [DebuggerNonUserCode]
    public SignedData(SignedData other) : this()
    {
        crxId_ = other.crxId_;
        _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [DebuggerNonUserCode]
    public SignedData Clone()
    {
        return new SignedData(this);
    }

    /// <summary>Field number for the "crx_id" field.</summary>
    public const int CrxIdFieldNumber = 1;
    private pb::ByteString crxId_ = pb::ByteString.Empty;
    /// <summary>
    /// This is simple binary, not UTF-8 encoded mpdecimal; i.e. it is exactly
    /// 16 bytes long.
    /// </summary>
    [DebuggerNonUserCode]
    public pb::ByteString CrxId
    {
        get { return crxId_; }
        set
        {
            crxId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        }
    }

    [DebuggerNonUserCode]
    public override bool Equals(object other)
    {
        return Equals(other as SignedData);
    }

    [DebuggerNonUserCode]
    public bool Equals(SignedData other)
    {
        if (ReferenceEquals(other, null))
        {
            return false;
        }
        if (ReferenceEquals(other, this))
        {
            return true;
        }
        if (CrxId != other.CrxId) return false;
        return Equals(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public override int GetHashCode()
    {
        int hash = 1;
        if (CrxId.Length != 0) hash ^= CrxId.GetHashCode();
        if (_unknownFields != null)
        {
            hash ^= _unknownFields.GetHashCode();
        }
        return hash;
    }

    [DebuggerNonUserCode]
    public override string ToString()
    {
        return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [DebuggerNonUserCode]
    public void WriteTo(pb::CodedOutputStream output)
    {
        if (CrxId.Length != 0)
        {
            output.WriteRawTag(10);
            output.WriteBytes(CrxId);
        }
        if (_unknownFields != null)
        {
            _unknownFields.WriteTo(output);
        }
    }

    [DebuggerNonUserCode]
    public int CalculateSize()
    {
        int size = 0;
        if (CrxId.Length != 0)
        {
            size += 1 + pb::CodedOutputStream.ComputeBytesSize(CrxId);
        }
        if (_unknownFields != null)
        {
            size += _unknownFields.CalculateSize();
        }
        return size;
    }

    [DebuggerNonUserCode]
    public void MergeFrom(SignedData other)
    {
        if (other == null)
        {
            return;
        }
        if (other.CrxId.Length != 0)
        {
            CrxId = other.CrxId;
        }
        _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public void MergeFrom(pb::CodedInputStream input)
    {
        uint tag;
        while ((tag = input.ReadTag()) != 0)
        {
            switch (tag)
            {
                default:
                    _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                    break;
                case 10:
                    {
                        CrxId = input.ReadBytes();
                        break;
                    }
            }
        }
    }

}
#endregion
#endregion Designer generated code
//
//由协议缓冲区编译器生成。不要编辑!
//资料来源:test.proto
// 
#pragma警告禁用15910612021
#区域设计器生成的代码
使用pb=Google.Protobuf;
使用pbc=Google.Protobuf.Collections;
使用pbr=Google.Protobuf.Reflection;
使用scg=System.Collections.Generic;
///test.proto生成的反射信息的持有者
公共静态部分类TestReflection
{
#区域描述符
///test.proto的文件描述符
公共静态pbr::FileDescriptor描述符
{
获取{返回描述符;}
}
私有静态pbr::FileDescriptor描述符;
静态TestReflection()
{
字节[]描述符数据=System.Convert.FromBase64String(
字符串。Concat(
“CGP0ZXN0LNB3B3RVIOOBCG1DCNHGAWXLSGVHZGVYEIWKD3NOYTI1NL93AXRO”,
“X3JzYRgCIAMoCzITLkFzeW1tZXRyaWNLZXlQcm9vZhIuChFzaGEyNTZfd2l0”,
“AF9LY2RZYRGDIAMOCZITLKFZEW1TZXRYANGLZXLQCM9VZHIBCHJZAWDUZWRF”,
“aGVhZGVyX2RhdGEYkE4gASgMIjsKEkFzeW1tZXRyaWNLZXlQcm9vZhISCgpw”,
“dwjsawnfa2v5gagasgmehekcxnpz25hdhvyzrgciaeodciccgptawduzwre”,
“yxrheg4kbmnyef9pzbgbbiaeodgigchjvdg8z”);
descriptor=pbr::FileDescriptor.FromGeneratedCode(descriptorData,
新的pbr::FileDescriptor[]{},
新pbr::GeneratedClrTypeInfo(null,null,新pbr::GeneratedClrTyp
// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: test.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code

using pb = Google.Protobuf;
using pbc = Google.Protobuf.Collections;
using pbr = Google.Protobuf.Reflection;
using scg = System.Collections.Generic;
/// <summary>Holder for reflection information generated from test.proto</summary>
public static partial class TestReflection
{

    #region Descriptor
    /// <summary>File descriptor for test.proto</summary>
    public static pbr::FileDescriptor Descriptor
    {
        get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static TestReflection()
    {
        byte[] descriptorData = System.Convert.FromBase64String(
            string.Concat(
              "Cgp0ZXN0LnByb3RvIooBCg1DcnhGaWxlSGVhZGVyEiwKD3NoYTI1Nl93aXRo",
              "X3JzYRgCIAMoCzITLkFzeW1tZXRyaWNLZXlQcm9vZhIuChFzaGEyNTZfd2l0",
              "aF9lY2RzYRgDIAMoCzITLkFzeW1tZXRyaWNLZXlQcm9vZhIbChJzaWduZWRf",
              "aGVhZGVyX2RhdGEYkE4gASgMIjsKEkFzeW1tZXRyaWNLZXlQcm9vZhISCgpw",
              "dWJsaWNfa2V5GAEgASgMEhEKCXNpZ25hdHVyZRgCIAEoDCIcCgpTaWduZWRE",
              "YXRhEg4KBmNyeF9pZBgBIAEoDGIGcHJvdG8z"));
        descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
            new pbr::FileDescriptor[] { },
            new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
      new pbr::GeneratedClrTypeInfo(typeof(CrxFileHeader), CrxFileHeader.Parser, new[]{ "Sha256WithRsa", "Sha256WithEcdsa", "SignedHeaderData" }, null, null, null, null),
      new pbr::GeneratedClrTypeInfo(typeof(AsymmetricKeyProof), AsymmetricKeyProof.Parser, new[]{ "PublicKey", "Signature" }, null, null, null, null),
      new pbr::GeneratedClrTypeInfo(typeof(SignedData), SignedData.Parser, new[]{ "CrxId" }, null, null, null, null)
            }));
    }
    #endregion

}
#region Messages
public sealed partial class CrxFileHeader : pb::IMessage<CrxFileHeader>
{
    private static readonly pb::MessageParser<CrxFileHeader> _parser = new pb::MessageParser<CrxFileHeader>(() => new CrxFileHeader());
    private pb::UnknownFieldSet _unknownFields;
    [DebuggerNonUserCode]
    public static pb::MessageParser<CrxFileHeader> Parser { get { return _parser; } }

    [DebuggerNonUserCode]
    public static pbr::MessageDescriptor Descriptor
    {
        get { return TestReflection.Descriptor.MessageTypes[0]; }
    }

    [DebuggerNonUserCode]
    pbr::MessageDescriptor pb::IMessage.Descriptor
    {
        get { return Descriptor; }
    }

    [DebuggerNonUserCode]
    public CrxFileHeader()
    {
        OnConstruction();
    }

    partial void OnConstruction();

    [DebuggerNonUserCode]
    public CrxFileHeader(CrxFileHeader other) : this()
    {
        sha256WithRsa_ = other.sha256WithRsa_.Clone();
        sha256WithEcdsa_ = other.sha256WithEcdsa_.Clone();
        signedHeaderData_ = other.signedHeaderData_;
        _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [DebuggerNonUserCode]
    public CrxFileHeader Clone()
    {
        return new CrxFileHeader(this);
    }

    /// <summary>Field number for the "sha256_with_rsa" field.</summary>
    public const int Sha256WithRsaFieldNumber = 2;
    private static readonly pb::FieldCodec<AsymmetricKeyProof> _repeated_sha256WithRsa_codec
        = pb::FieldCodec.ForMessage(18, AsymmetricKeyProof.Parser);
    private readonly pbc::RepeatedField<AsymmetricKeyProof> sha256WithRsa_ = new pbc::RepeatedField<AsymmetricKeyProof>();
    /// <summary>
    /// PSS signature with RSA public key. The public key is formatted as a
    /// X.509 SubjectPublicKeyInfo block, as in CRXâ‚‚. In the common case of a
    /// developer key proof, the first 128 bits of the SHA-256 hash of the 
    /// public key must equal the crx_id.
    /// </summary>
    [DebuggerNonUserCode]
    public pbc::RepeatedField<AsymmetricKeyProof> Sha256WithRsa
    {
        get { return sha256WithRsa_; }
    }

    /// <summary>Field number for the "sha256_with_ecdsa" field.</summary>
    public const int Sha256WithEcdsaFieldNumber = 3;
    private static readonly pb::FieldCodec<AsymmetricKeyProof> _repeated_sha256WithEcdsa_codec
        = pb::FieldCodec.ForMessage(26, AsymmetricKeyProof.Parser);
    private readonly pbc::RepeatedField<AsymmetricKeyProof> sha256WithEcdsa_ = new pbc::RepeatedField<AsymmetricKeyProof>();
    /// <summary>
    /// ECDSA signature, using the NIST P-256 curve. Public key appears in
    /// named-curve format.
    /// The pinned algorithm will be this, at least on 2017-01-01.
    /// </summary>
    [DebuggerNonUserCode]
    public pbc::RepeatedField<AsymmetricKeyProof> Sha256WithEcdsa
    {
        get { return sha256WithEcdsa_; }
    }

    /// <summary>Field number for the "signed_header_data" field.</summary>
    public const int SignedHeaderDataFieldNumber = 10000;
    private pb::ByteString signedHeaderData_ = pb::ByteString.Empty;
    /// <summary>
    /// The binary form of a SignedData message. We do not use a nested 
    /// SignedData message, as handlers of this message must verify the proofs
    /// on exactly these bytes, so it is convenient to parse in two steps.
    ///
    /// All proofs in this CrxFile message are on the value
    /// "CRX3 SignedData\x00" + signed_header_size + signed_header_data +
    /// archive, where "\x00" indicates an octet with value 0, "CRX3 SignedData"
    /// is encoded using UTF-8, signed_header_size is the size in octets of the
    /// contents of this field and is encoded using 4 octets in little-endian
    /// order, signed_header_data is exactly the content of this field, and
    /// archive is the remaining contents of the file following the header.
    /// </summary>
    [DebuggerNonUserCode]
    public pb::ByteString SignedHeaderData
    {
        get { return signedHeaderData_; }
        set
        {
            signedHeaderData_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        }
    }

    [DebuggerNonUserCode]
    public override bool Equals(object other)
    {
        return Equals(other as CrxFileHeader);
    }

    [DebuggerNonUserCode]
    public bool Equals(CrxFileHeader other)
    {
        if (ReferenceEquals(other, null))
        {
            return false;
        }
        if (ReferenceEquals(other, this))
        {
            return true;
        }
        if (!sha256WithRsa_.Equals(other.sha256WithRsa_)) return false;
        if (!sha256WithEcdsa_.Equals(other.sha256WithEcdsa_)) return false;
        if (SignedHeaderData != other.SignedHeaderData) return false;
        return Equals(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public override int GetHashCode()
    {
        int hash = 1;
        hash ^= sha256WithRsa_.GetHashCode();
        hash ^= sha256WithEcdsa_.GetHashCode();
        if (SignedHeaderData.Length != 0) hash ^= SignedHeaderData.GetHashCode();
        if (_unknownFields != null)
        {
            hash ^= _unknownFields.GetHashCode();
        }
        return hash;
    }

    [DebuggerNonUserCode]
    public override string ToString()
    {
        return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [DebuggerNonUserCode]
    public void WriteTo(pb::CodedOutputStream output)
    {
        sha256WithRsa_.WriteTo(output, _repeated_sha256WithRsa_codec);
        sha256WithEcdsa_.WriteTo(output, _repeated_sha256WithEcdsa_codec);
        if (SignedHeaderData.Length != 0)
        {
            output.WriteRawTag(130, 241, 4);
            output.WriteBytes(SignedHeaderData);
        }
        if (_unknownFields != null)
        {
            _unknownFields.WriteTo(output);
        }
    }

    [DebuggerNonUserCode]
    public int CalculateSize()
    {
        int size = 0;
        size += sha256WithRsa_.CalculateSize(_repeated_sha256WithRsa_codec);
        size += sha256WithEcdsa_.CalculateSize(_repeated_sha256WithEcdsa_codec);
        if (SignedHeaderData.Length != 0)
        {
            size += 3 + pb::CodedOutputStream.ComputeBytesSize(SignedHeaderData);
        }
        if (_unknownFields != null)
        {
            size += _unknownFields.CalculateSize();
        }
        return size;
    }

    [DebuggerNonUserCode]
    public void MergeFrom(CrxFileHeader other)
    {
        if (other == null)
        {
            return;
        }
        sha256WithRsa_.Add(other.sha256WithRsa_);
        sha256WithEcdsa_.Add(other.sha256WithEcdsa_);
        if (other.SignedHeaderData.Length != 0)
        {
            SignedHeaderData = other.SignedHeaderData;
        }
        _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public void MergeFrom(pb::CodedInputStream input)
    {
        uint tag;
        while ((tag = input.ReadTag()) != 0)
        {
            switch (tag)
            {
                default:
                    _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                    break;
                case 18:
                    {
                        sha256WithRsa_.AddEntriesFrom(input, _repeated_sha256WithRsa_codec);
                        break;
                    }
                case 26:
                    {
                        sha256WithEcdsa_.AddEntriesFrom(input, _repeated_sha256WithEcdsa_codec);
                        break;
                    }
                case 80002:
                    {
                        SignedHeaderData = input.ReadBytes();
                        break;
                    }
            }
        }
    }

}

public sealed partial class AsymmetricKeyProof : pb::IMessage<AsymmetricKeyProof>
{
    private static readonly pb::MessageParser<AsymmetricKeyProof> _parser = new pb::MessageParser<AsymmetricKeyProof>(() => new AsymmetricKeyProof());
    private pb::UnknownFieldSet _unknownFields;
    [DebuggerNonUserCode]
    public static pb::MessageParser<AsymmetricKeyProof> Parser { get { return _parser; } }

    [DebuggerNonUserCode]
    public static pbr::MessageDescriptor Descriptor
    {
        get { return TestReflection.Descriptor.MessageTypes[1]; }
    }

    [DebuggerNonUserCode]
    pbr::MessageDescriptor pb::IMessage.Descriptor
    {
        get { return Descriptor; }
    }

    [DebuggerNonUserCode]
    public AsymmetricKeyProof()
    {
        OnConstruction();
    }

    partial void OnConstruction();

    [DebuggerNonUserCode]
    public AsymmetricKeyProof(AsymmetricKeyProof other) : this()
    {
        publicKey_ = other.publicKey_;
        signature_ = other.signature_;
        _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [DebuggerNonUserCode]
    public AsymmetricKeyProof Clone()
    {
        return new AsymmetricKeyProof(this);
    }

    /// <summary>Field number for the "public_key" field.</summary>
    public const int PublicKeyFieldNumber = 1;
    private pb::ByteString publicKey_ = pb::ByteString.Empty;
    [DebuggerNonUserCode]
    public pb::ByteString PublicKey
    {
        get { return publicKey_; }
        set
        {
            publicKey_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        }
    }

    /// <summary>Field number for the "signature" field.</summary>
    public const int SignatureFieldNumber = 2;
    private pb::ByteString signature_ = pb::ByteString.Empty;
    [DebuggerNonUserCode]
    public pb::ByteString Signature
    {
        get { return signature_; }
        set
        {
            signature_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        }
    }

    [DebuggerNonUserCode]
    public override bool Equals(object other)
    {
        return Equals(other as AsymmetricKeyProof);
    }

    [DebuggerNonUserCode]
    public bool Equals(AsymmetricKeyProof other)
    {
        if (ReferenceEquals(other, null))
        {
            return false;
        }
        if (ReferenceEquals(other, this))
        {
            return true;
        }
        if (PublicKey != other.PublicKey) return false;
        if (Signature != other.Signature) return false;
        return Equals(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public override int GetHashCode()
    {
        int hash = 1;
        if (PublicKey.Length != 0) hash ^= PublicKey.GetHashCode();
        if (Signature.Length != 0) hash ^= Signature.GetHashCode();
        if (_unknownFields != null)
        {
            hash ^= _unknownFields.GetHashCode();
        }
        return hash;
    }

    [DebuggerNonUserCode]
    public override string ToString()
    {
        return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [DebuggerNonUserCode]
    public void WriteTo(pb::CodedOutputStream output)
    {
        if (PublicKey.Length != 0)
        {
            output.WriteRawTag(10);
            output.WriteBytes(PublicKey);
        }
        if (Signature.Length != 0)
        {
            output.WriteRawTag(18);
            output.WriteBytes(Signature);
        }
        if (_unknownFields != null)
        {
            _unknownFields.WriteTo(output);
        }
    }

    [DebuggerNonUserCode]
    public int CalculateSize()
    {
        int size = 0;
        if (PublicKey.Length != 0)
        {
            size += 1 + pb::CodedOutputStream.ComputeBytesSize(PublicKey);
        }
        if (Signature.Length != 0)
        {
            size += 1 + pb::CodedOutputStream.ComputeBytesSize(Signature);
        }
        if (_unknownFields != null)
        {
            size += _unknownFields.CalculateSize();
        }
        return size;
    }

    [DebuggerNonUserCode]
    public void MergeFrom(AsymmetricKeyProof other)
    {
        if (other == null)
        {
            return;
        }
        if (other.PublicKey.Length != 0)
        {
            PublicKey = other.PublicKey;
        }
        if (other.Signature.Length != 0)
        {
            Signature = other.Signature;
        }
        _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public void MergeFrom(pb::CodedInputStream input)
    {
        uint tag;
        while ((tag = input.ReadTag()) != 0)
        {
            switch (tag)
            {
                default:
                    _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                    break;
                case 10:
                    {
                        PublicKey = input.ReadBytes();
                        break;
                    }
                case 18:
                    {
                        Signature = input.ReadBytes();
                        break;
                    }
            }
        }
    }

}

public sealed partial class SignedData : pb::IMessage<SignedData>
{
    private static readonly pb::MessageParser<SignedData> _parser = new pb::MessageParser<SignedData>(() => new SignedData());
    private pb::UnknownFieldSet _unknownFields;
    [DebuggerNonUserCode]
    public static pb::MessageParser<SignedData> Parser { get { return _parser; } }

    [DebuggerNonUserCode]
    public static pbr::MessageDescriptor Descriptor
    {
        get { return TestReflection.Descriptor.MessageTypes[2]; }
    }

    [DebuggerNonUserCode]
    pbr::MessageDescriptor pb::IMessage.Descriptor
    {
        get { return Descriptor; }
    }

    [DebuggerNonUserCode]
    public SignedData()
    {
        OnConstruction();
    }

    partial void OnConstruction();

    [DebuggerNonUserCode]
    public SignedData(SignedData other) : this()
    {
        crxId_ = other.crxId_;
        _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [DebuggerNonUserCode]
    public SignedData Clone()
    {
        return new SignedData(this);
    }

    /// <summary>Field number for the "crx_id" field.</summary>
    public const int CrxIdFieldNumber = 1;
    private pb::ByteString crxId_ = pb::ByteString.Empty;
    /// <summary>
    /// This is simple binary, not UTF-8 encoded mpdecimal; i.e. it is exactly
    /// 16 bytes long.
    /// </summary>
    [DebuggerNonUserCode]
    public pb::ByteString CrxId
    {
        get { return crxId_; }
        set
        {
            crxId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        }
    }

    [DebuggerNonUserCode]
    public override bool Equals(object other)
    {
        return Equals(other as SignedData);
    }

    [DebuggerNonUserCode]
    public bool Equals(SignedData other)
    {
        if (ReferenceEquals(other, null))
        {
            return false;
        }
        if (ReferenceEquals(other, this))
        {
            return true;
        }
        if (CrxId != other.CrxId) return false;
        return Equals(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public override int GetHashCode()
    {
        int hash = 1;
        if (CrxId.Length != 0) hash ^= CrxId.GetHashCode();
        if (_unknownFields != null)
        {
            hash ^= _unknownFields.GetHashCode();
        }
        return hash;
    }

    [DebuggerNonUserCode]
    public override string ToString()
    {
        return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [DebuggerNonUserCode]
    public void WriteTo(pb::CodedOutputStream output)
    {
        if (CrxId.Length != 0)
        {
            output.WriteRawTag(10);
            output.WriteBytes(CrxId);
        }
        if (_unknownFields != null)
        {
            _unknownFields.WriteTo(output);
        }
    }

    [DebuggerNonUserCode]
    public int CalculateSize()
    {
        int size = 0;
        if (CrxId.Length != 0)
        {
            size += 1 + pb::CodedOutputStream.ComputeBytesSize(CrxId);
        }
        if (_unknownFields != null)
        {
            size += _unknownFields.CalculateSize();
        }
        return size;
    }

    [DebuggerNonUserCode]
    public void MergeFrom(SignedData other)
    {
        if (other == null)
        {
            return;
        }
        if (other.CrxId.Length != 0)
        {
            CrxId = other.CrxId;
        }
        _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [DebuggerNonUserCode]
    public void MergeFrom(pb::CodedInputStream input)
    {
        uint tag;
        while ((tag = input.ReadTag()) != 0)
        {
            switch (tag)
            {
                default:
                    _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                    break;
                case 10:
                    {
                        CrxId = input.ReadBytes();
                        break;
                    }
            }
        }
    }

}
#endregion
#endregion Designer generated code