从snk文件中获取.NET PublicKeyToken?

29

如何从snk文件中获取PublicKeyToken?使用命令行工具。我考虑使用sn.exe,但找不到合适的参数。

4个回答

43

如果您想使用sn.exe工具:

sn -p yourkey.snk publickey.snk

现在有一个publickey.snk,只包含公钥。

sn -tp publickey.snk

现在你拥有公钥和公钥标记。


给定一个包含 snk 文件的 byte[],例如:

byte[] snk = File.ReadAllBytes("YourSnkFile.snk");

使用

byte[] publicKey = GetPublicKey(snk);
byte[] publicKeyToken = GetPublicKeyToken(publicKey);

使用这些实用方法

public static byte[] GetPublicKey(byte[] snk)
{
    var snkp = new StrongNameKeyPair(snk);
    byte[] publicKey = snkp.PublicKey;
    return publicKey;
}

public static byte[] GetPublicKeyToken(byte[] publicKey)
{
    using (var csp = new SHA1CryptoServiceProvider())
    {
        byte[] hash = csp.ComputeHash(publicKey);

        byte[] token = new byte[8];

        for (int i = 0; i < 8; i++)
        {
            token[i] = hash[hash.Length - i - 1];
        }

        return token;
    }
}

好的回答。谢谢 +1 - Tarik
仅供参考,它只在Windows上适用于net4x,并在netcore中引发“System.PlatformNotSupportedException”异常。 - M.Hassan
1
@M.Hassan 很遗憾,你是正确的。关于这个问题有一个开放的问题(https://github.com/dotnet/dotnet-api-docs/issues/4896),但它只存在于文档中。 - xanatos

26

使用sn.exe从.snk文件中提取公钥令牌需要两个步骤。

使用sn.exe从YourFile.snk中提取公钥并将其写入Token.snk

sn -p YourFile.snk Token.snk

使用sn.exe从Token.snk中提取公钥令牌并将其写入PublicToken.txt

sn -t Token.snk > PublicToken.txt


4
@specializt说他需要一个编程解决方案吗?“如何使用命令行工具从snk文件中获取PublicKeyToken?” - Jehof
不知道为什么,但这导致了一个比我预期的要短得多的密钥... @Ivan G. 的 PowerShell 解决方案给了我我所需要的。 - Scott Langham
1
如果有其他人遇到了这个问题,“sn -tp Token.snk”会给出令牌和实际的公钥。 - Carter Musick

7
除了@xanatos的回答外,如果有人需要,这是PowerShell版本:
function Get-SnkPublicKey([string]$FilePath)
{
    $bytes = [System.IO.File]::ReadAllBytes($FilePath)
    $pair = New-Object System.Reflection.StrongNameKeyPair -ArgumentList @(,$bytes)
    $publicKey = $pair.PublicKey

    #[System.Convert]::ToBase64String($publicKey)
    $hexes = [System.BitConverter]::ToString($publicKey);
    $hexes.Replace("-", "")
}

1
很棒的东西,但它打印了完整的公钥而不是其令牌。 - honzajscz

1

由于 StrongNameKeyPair 在 net5.0 或 netstandard2.1 中不可用,而且 sn.exe 需要管理员权限,因此您可以使用 RSACryptoServiceProvider 类:

$bytes = Get-Content "YOUR-PROJECT.snk" -AsByteStream
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider
$rsa.ImportCspBlob($bytes)

$publicKey = $rsa.ExportRSAPublicKey()
$privateKey = $rsa.ExportRSAPrivateKey()

static void Main()
{
  byte[] bytes = File.ReadAllBytes("YOUR-PROJECT.snk");
  RSACryptoServiceProvider rsa = new();

  rsa.ImportCspBlob(bytes);

  byte[] publicKey = rsa.ExportRSAPublicKey();
  byte[] privateKey = rsa.ExportRSAPrivateKey();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接