我想了解一下Windows Store和APPX包的内部情况。 package.appxmanifest有一个<Identity>
元素,它具有包名,发布者和版本属性,例如
<Identity
Name="MyCompany.MyGreatApp"
Publisher="CN=B408A06D-44F7-4860-A12E-644DD44FA743"
Version="1.0.0.3" />
显然,当我在VS2013中打开此清单并转到Packaging选项卡时,它会显示一个只读的“Package Family Name”字段,它是包名称,下划线和类似 a的内容的串联发布者字符串的奇怪哈希。
MyCompany.MyGreatApp_f08ys7xx9zb3y
如何计算此哈希值(也称为 PublisherId )?另请参阅PackageId class或PACKAGE_ID structure。
以下是您渴望加密分析师的一些示例值。它是13个小写字母和数字,因此近似“质量”是67位。谢谢!
8wekyb3d8bbwe CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
amge560j0aq9g CN=C357A519-CEE3-4675-9EF4-44DE1D99A5D6
a2xxwqz7shah6 CN=07AACB4D-E1D7-4606-AF0F-77713A7C52F6
cw5n1h2txyewy CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
54ggd3ev8bvz6 CN=2180B9A4-DDFD-4BFD-8D7E-EADC9C394EF5
azstdzfk4mfqj CN=246910D1-A42D-4A04-8CF1-0C2A5CD42D4D
rxzpp8adhbvh8 CN=7882B094-0135-443F-8362-164AA239F2A0
pwh22gvzcj20c CN=9C2E3884-8027-4E71-97C7-BB7731A649A4
q4d96b2w5wcc2 CN=DCD4AC3C-C7E0-46FF-8387-51FDC8CBC467
r6rtpscs7gwyg CN=54157592-46DE-47CD-AF04-3B89DE46E29B
8xx8rvfyw5nnt CN=6E08453F-9BA7-4311-999C-D22FBA2FB1B8
kzf8qxf38zg5c CN=Skype Software Sarl, O=Microsoft Corporation, L=Luxembourg, S=Luxembourg, C=LU
a76a11dkgb644 CN=40886CD1-D5C5-48D6-B914-AB6E72010FFC
6bhtb546zcxnj CN=BBC567E9-A52C-43A3-A890-F8B17D68310E
46hhcags7zat8 CN=ABF01D82-FF53-447D-B7E8-61B6F2105F68
pd2za7f9waemw CN=B408A06D-44F7-4860-A12E-644DD44FA740
h0ed56e8a88dc CN=B408A06D-44F7-4860-A12E-644DD44FA741
wcvtzcf7freyj CN=B408A06D-44F7-4860-A12E-644DD44FA742
f08ys7xx9zb3y CN=B408A06D-44F7-4860-A12E-644DD44FA743
85zvc56jp30ec CN=C408A06D-44F7-4860-A12E-644DD44FA743
x4nmjqajw9mv6 CN=D408A06D-44F7-4860-A12E-644DD44FA743
qrhphajnj16d4 CN=E408A06D-44F7-4860-A12E-644DD44FA743
答案 0 :(得分:9)
我猜测PublisherId值的构造方式非常接近。我听到一些窃窃私语......
该值是Crockford’s Base32(SHA-256)中发布商字符串的UTF-16哈希的前八个字节的little endian编码。我有一个很好的实现,我使用我的问题中的示例值进行了验证。
答案 1 :(得分:3)
或者您只是使用Kernel32.dll方法PackageFamilyNameFromId:
private static string GetPackageFamilyName(string name, string publisherId)
{
string packageFamilyName = null;
PACKAGE_ID packageId = new PACKAGE_ID
{
name = name,
publisher = publisherId
};
uint packageFamilyNameLength = 0;
//First get the length of the Package Name -> Pass NULL as Output Buffer
if (PackageFamilyNameFromId(packageId, ref packageFamilyNameLength, null) == 122) //ERROR_INSUFFICIENT_BUFFER
{
StringBuilder packageFamilyNameBuilder = new StringBuilder((int)packageFamilyNameLength);
if (PackageFamilyNameFromId(packageId, ref packageFamilyNameLength, packageFamilyNameBuilder) == 0)
{
packageFamilyName = packageFamilyNameBuilder.ToString();
}
}
return packageFamilyName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 4)]
private class PACKAGE_ID
{
public uint reserved;
public uint processorArchitecture;
public ulong version;
public string name;
public string publisher;
public string resourceId;
public string publisherId;
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern uint PackageFamilyNameFromId(PACKAGE_ID packageId, ref uint packageFamilyNameLength, StringBuilder packageFamilyName);
public static void TestMethod()
{
GetPackageFamilyName("MyCompany.TestApp", "CN=YourPublisherId");
}
答案 2 :(得分:1)
上周五联系Tomas寻求帮助;因为我无法正常工作。 但是最后我设法使它起作用。 Tomas提供的答案包含所有必需的组件,但是我很难实现它。尤其是Crockford的Base32。
我已经为其创建了一个PowerShell函数。希望它可以帮助更多的人。就像Tomas已经写过的一样:
最终字符串应为PublisherId。
托马斯;谢谢您的帮助。
Function Get-PublisherIdFromPublisher ($Publisher) {
$EncUTF16LE = [system.Text.Encoding]::Unicode
$EncSha256 = [System.Security.Cryptography.HashAlgorithm]::Create("SHA256")
# Convert to UTF16 Little Endian
$UTF16LE = $EncUTF16LE.GetBytes($Publisher)
# Calculate SHA256 hash on UTF16LE Byte array. Store first 8 bytes in new Byte Array
$Bytes = @()
(($EncSha256.ComputeHasH($UTF16LE))[0..7]) | % { $Bytes += '{0:x2}' -f $_ }
# Convert Byte Array to Binary string; Adding padding zeros on end to it has 13*5 bytes
$BytesAsBinaryString = -join $Bytes.ForEach{ [convert]::tostring([convert]::ToByte($_,16),2).padleft(8,'0') }
$BytesAsBinaryString = $BytesAsBinaryString.PadRight(65,'0')
# Crockford Base32 encode. Read each 5 bits; convert to decimal. Lookup position in lookup table
$Coded = $null
For ($i=0;$i -lt (($BytesAsBinaryString.Length)); $i+=5) {
$String = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
[int]$Int = [convert]::Toint32($BytesAsBinaryString.Substring($i,5),2)
$Coded += $String.Substring($Int,1)
}
Return $Coded.tolower()
}