Update the read of publisher id.

This commit is contained in:
Bruce
2026-04-14 16:48:39 +08:00
parent 9fbcbdd7e9
commit 8a44ae0ebd
4 changed files with 75 additions and 6 deletions

View File

@@ -178,6 +178,7 @@ namespace AppxPackage
} }
public string Publisher { get { return StringValue (1); } } public string Publisher { get { return StringValue (1); } }
public string ResourceId { get { return StringValue (4); } } public string ResourceId { get { return StringValue (4); } }
public string PublisherId => PublisherIdHelper.GetPublisherId (Publisher);
public DataUtils.Version Version public DataUtils.Version Version
{ {
get get
@@ -197,7 +198,9 @@ namespace AppxPackage
publisher = Publisher, publisher = Publisher,
resource_id = ResourceId, resource_id = ResourceId,
architecture = ProcessArchitecture.Select (e => (int)e).ToList (), architecture = ProcessArchitecture.Select (e => (int)e).ToList (),
version = Version.BuildJSON () version = Version.BuildJSON (),
publisher_id = PublisherId,
_publisher_id = "Note: The publisher id obtained may be inaccurate."
}; };
} }
} }

View File

@@ -13,6 +13,7 @@ using ICSharpCode.SharpZipLib;
using System.IO; using System.IO;
using System.Xml; using System.Xml;
using ICSharpCode.SharpZipLib.Zip; using ICSharpCode.SharpZipLib.Zip;
using System.Security.Cryptography;
//using PriFormat; //using PriFormat;
namespace AppxPackage namespace AppxPackage
{ {
@@ -108,6 +109,47 @@ namespace AppxPackage
return ret; return ret;
} }
} }
[ComVisible (true)]
internal static class PublisherIdHelper
{
// Base32 编码表 (Crockford 变体,去掉 I L O U 避免混淆)
private const string Base32Chars = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
/// <summary>
/// 从证书的可分辨名称 (Distinguished Name) 计算出对应的 Publisher ID。
/// </summary>
/// <param name="distinguishedName">
/// 证书 DN 字符串,例如 "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
/// </param>
/// <returns>13 位小写字母数字组成的 Publisher ID</returns>
/// <exception cref="ArgumentNullException">distinguishedName 为 null 时抛出</exception>
public static string GetPublisherId (string distinguishedName)
{
if (distinguishedName == null)
throw new ArgumentNullException (nameof (distinguishedName));
byte [] dnBytes = Encoding.Unicode.GetBytes (distinguishedName);
byte [] hash;
using (var sha256 = SHA256.Create ())
{
hash = sha256.ComputeHash (dnBytes);
}
byte [] first8Bytes = new byte [8];
Array.Copy (hash, 0, first8Bytes, 0, 8);
var binaryBuilder = new StringBuilder (64);
for (int i = 0; i < first8Bytes.Length; i++)
{
binaryBuilder.Append (Convert.ToString (first8Bytes [i], 2).PadLeft (8, '0'));
}
string binaryString = binaryBuilder.ToString ().PadRight (65, '0');
var resultBuilder = new StringBuilder (13);
for (int i = 0; i < 65; i += 5)
{
string fiveBits = binaryString.Substring (i, 5);
int index = Convert.ToInt32 (fiveBits, 2);
resultBuilder.Append (Base32Chars [index]);
}
return resultBuilder.ToString ().ToLowerInvariant ();
}
}
internal class PriAllValuesReader: IDisposable internal class PriAllValuesReader: IDisposable
{ {
public PackageReader pr = null; public PackageReader pr = null;
@@ -491,6 +533,7 @@ namespace AppxPackage
} }
public string Publisher { get { return StringValue (1); } } public string Publisher { get { return StringValue (1); } }
public string ResourceId { get { return StringValue (4); } } public string ResourceId { get { return StringValue (4); } }
public string PublisherId => PublisherIdHelper.GetPublisherId (Publisher);
public DataUtils.Version Version public DataUtils.Version Version
{ {
get get
@@ -519,7 +562,9 @@ namespace AppxPackage
resource_id = ResourceId, resource_id = ResourceId,
architecture = ProcessArchitecture.Select (e => (int)e).ToList (), architecture = ProcessArchitecture.Select (e => (int)e).ToList (),
version = Version.BuildJSON (), version = Version.BuildJSON (),
realver = RealVersion.BuildJSON () realver = RealVersion.BuildJSON (),
publisher_id = PublisherId,
_publisher_id = "Note: The publisher id obtained may be inaccurate."
}; };
} }
} }
@@ -1873,7 +1918,9 @@ namespace AppxPackage
}).ToList (), }).ToList (),
familyName = id.FamilyName, familyName = id.FamilyName,
fullName = id.FullName, fullName = id.FullName,
resourceId = id.ResourceId resourceId = id.ResourceId,
publisherId = id.PublisherId,
_publisherId = "Note: The publisher id obtained may be inaccurate."
}; };
#endregion #endregion
#region prerequistes #region prerequistes
@@ -2194,6 +2241,10 @@ namespace AppxPackage
nodeid.AppendChild (nodeidfamily); nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidfamily); nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidresid); nodeid.AppendChild (nodeidresid);
var nodeidpublid = xml.CreateElement ("PublisherId");
nodeidpublid.InnerText = id.PublisherId;
nodeidpublid.SetAttribute ("Description", "Note: The publisher id obtained may be inaccurate.");
nodeid.AppendChild (nodeidpublid);
root.AppendChild (nodeid); root.AppendChild (nodeid);
} }
#endregion #endregion
@@ -2620,7 +2671,9 @@ namespace AppxPackage
}).ToList (), }).ToList (),
familyName = id.FamilyName, familyName = id.FamilyName,
fullName = id.FullName, fullName = id.FullName,
resourceId = id.ResourceId resourceId = id.ResourceId,
publisherId = id.PublisherId,
_publisherId = "Note: The publisher id obtained may be inaccurate."
}; };
#endregion #endregion
#region prerequistes #region prerequistes
@@ -2949,6 +3002,10 @@ namespace AppxPackage
nodeid.AppendChild (nodeidfamily); nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidfamily); nodeid.AppendChild (nodeidfamily);
nodeid.AppendChild (nodeidresid); nodeid.AppendChild (nodeidresid);
var nodeidpublid = xml.CreateElement ("PublisherId");
nodeidpublid.InnerText = id.PublisherId;
nodeidpublid.SetAttribute ("Description", "Note: The publisher id obtained may be inaccurate.");
nodeid.AppendChild (nodeidpublid);
root.AppendChild (nodeid); root.AppendChild (nodeid);
} }
#endregion #endregion

View File

@@ -137,7 +137,9 @@ namespace PkgCLI
}).ToList (), }).ToList (),
familyName = id.FamilyName, familyName = id.FamilyName,
fullName = id.FullName, fullName = id.FullName,
resourceId = id.ResourceId resourceId = id.ResourceId,
publisherId = id.PublisherId,
_publisherId = "Note: The publisher id obtained may be inaccurate."
}, },
properties = new { properties = new {
displayName = prop.DisplayName, displayName = prop.DisplayName,
@@ -574,7 +576,9 @@ namespace PkgCLI
}).ToList (), }).ToList (),
familyName = id.FamilyName, familyName = id.FamilyName,
fullName = id.FullName, fullName = id.FullName,
resourceId = id.ResourceId resourceId = id.ResourceId,
publisherId = id.PublisherId,
_publisherId = "Note: The publisher id obtained may be inaccurate."
}, },
properties = new { properties = new {
displayName = prop.DisplayName, displayName = prop.DisplayName,

View File

@@ -104,6 +104,10 @@
<td>Resource ID</td> <td>Resource ID</td>
<td name="resource_id"></td> <td name="resource_id"></td>
</tr> </tr>
<tr title="Note: The publisher id obtained may be inaccurate.">
<td>Publisher ID</td>
<td name="publisher_id"></td>
</tr>
<tr class="spec"> <tr class="spec">
<td colspan="2">Properties</td> <td colspan="2">Properties</td>
</tr> </tr>
@@ -319,6 +323,7 @@
t.querySelector("[name='package_family_name']").textContent = pi.identity.package_family_name; t.querySelector("[name='package_family_name']").textContent = pi.identity.package_family_name;
t.querySelector("[name='package_full_name']").textContent = pi.identity.package_full_name; t.querySelector("[name='package_full_name']").textContent = pi.identity.package_full_name;
t.querySelector("[name='resource_id']").textContent = pi.identity.resource_id; t.querySelector("[name='resource_id']").textContent = pi.identity.resource_id;
t.querySelector("[name='publisher_id']").textContent = pi.identity.publisher_id;
t.querySelector("[name='display_name']").textContent = pi.properties.display_name; t.querySelector("[name='display_name']").textContent = pi.properties.display_name;
t.querySelector("[name='publisher_display_name']").textContent = pi.properties.publisher_display_name; t.querySelector("[name='publisher_display_name']").textContent = pi.properties.publisher_display_name;
t.querySelector("[name='description']").textContent = pi.properties.description; t.querySelector("[name='description']").textContent = pi.properties.description;