C# 中签名程序集的公钥的结构是啥?

Posted

技术标签:

【中文标题】C# 中签名程序集的公钥的结构是啥?【英文标题】:What is the structure of the public key of a signed assembly in C#?C# 中签名程序集的公钥的结构是什么? 【发布时间】:2015-02-21 03:28:30 【问题描述】:

使用此代码检索公钥字节...

var pubKey = 
    AppDomain.CurrentDomain.DomainManager.EntryAssembly
        .GetName().GetPublicKey();

密钥开头(前 32 个字节)的常见结构是什么? 它不是 ASN.1,它可能不是可变的。我可以谷歌它并获得重复。

// 00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31

是全部颠倒还是只是其中的一部分(例如末尾的模数)? 52 53 41 31RSA1 的字符串。 我的密钥模数是 1024 位,所以我一直在寻找描述长度的东西。 0x0400 (00 04 B.E.) 将是 1024(位),0x80 将是 128(字节,1024/8)。

// 00 04 00 00 01 00 01 00

这些最后 4 到 6 是公共指数吗?大端还是小端?最后一个 null 是终止符还是间隔符?

调查RSAPKCS1SignatureFormatterRSAPKCS1SignatureDeformatter 的实现(.NET 和 Mono)并不容易。

删除编辑,回答自己的问题...除非有人提出更好的答案或添加包括原因在内的详细信息。

【问题讨论】:

【参考方案1】:

我不能停止咬指甲,试图从 CALG_RSA_SIGN = 0x00002400 向后工作,然后偶然发现 RSAPUBKEY,然后是 PUBLICKEYSTRUC,最后是 PublicKeyBlob。 好吧,现在我可以正式解析它了。 想知道 .NET 框架中是否已经有任何结构来处理这个问题?

https://msdn.microsoft.com/en-us/library/ee442238.aspx

哦,嘿,这些神奇的数字看起来很眼熟。它们是什么意思...

是https://msdn.microsoft.com/en-us/library/ms232463.aspx吗?

// 00 24 00 00 // 0x00002400 LE // PublicKeyBlob  SigAlgId ALG_ID = CALG_RSA_SIGN 
// 04 80 00 00 // 0x00008004 LE // PublicKeyBlob  HashAlgId ALG_ID = CALG_SHA1
// 94 00 00 00 // 0x00000094 LE // PublicKeyBlob  cbPublicKey dword = 148
// sizeof(PUBLICKEYSTRUC) is 8 + sizeof(RSAPUBKEY) is 12 + sizeof(modulus) is 128 = 148
// 06          // 0x06          // PUBLICKEYSTRUC bType byte = PUBLICKEYBLOB
// 02          // 0x02          // PUBLICKEYSTRUC bVersion byte = CUR_BLOB_VERSION
// 00 00       // 0x0000 LE     // PUBLICKEYSTRUC reserved word = 0
// 00 24 00 00 // 0x00002400 LE // PUBLICKEYSTRUC aiKeyAlg ALG_ID = CALG_RSA_SIGN 
// 52 53 41 31 // 'RSA1'        // RSAPUBKEY magic dword
// 00 04 00 00 // 0x00000400 LE // RSAPUBKEY bitlen dword
// 01 00 01 00 // 0x00010001 LE // RSAPUBKEY pubexp dword
// public modulus reversed follows in (bitlen/8) bytes

所以使用此信息(无法让 rsaCsp.ImportParameters 正常工作)...

var rsaCsp = new RSACryptoServiceProvider(BitLength);
rsaCsp.FromXmlString(string.Format(
    "<RSAKeyValue><Modulus>1</Modulus><Exponent>0</Exponent></RSAKeyValue>",
    Convert.ToBase64String(PubExp), Convert.ToBase64String(PubMod)));

现在您有一个有效的 rsaCsp 用于从您的程序集的 SN PK 进行签名验证。

【讨论】:

还有一个警告... PubExp 必须转换为字节并去除前导零字节(修剪高 0 字节,例如 01 00 01 00 -> 01 00 01 -> AQAB,而不是 AQABAA= =)。

以上是关于C# 中签名程序集的公钥的结构是啥?的主要内容,如果未能解决你的问题,请参考以下文章

C#进阶系列03 配置文件管理与程序集的引用版本重定向

C# 依赖同一个强签名程序集的不同版本

C# 防止 AppDomain 程序集的类实例访问文件

强命名程序集组成与作用

在 C# 中的程序集上下文中,激活范围指的是啥?

在项目模板中包含对我自己的程序集的引用的最佳方式是啥?