代码改变世界

由Public key生成Public key token

2013-04-01 06:35  左眼微笑右眼泪  阅读(2064)  评论(1编辑  收藏  举报

       在.NET程序中,强签名的时候,会用到密钥,一般是用私钥对进行哈希处理后的值进行RSA签名,然后把这个签名放在程序集的CLR头里面,同时把公钥也放在Assembly里面。公钥占160字节,有32字节的头和128字节的数据组成。有时候一个程序引用了很多程序集,如果把公钥完全记录在程序集里面,最后就会占用比较多的空间。为了节约空间并且方便使用,提出了公钥标记(public key token)的概念。公钥标记占8个字节,它是通过公钥算出来的,具体过程如下:

1.把公钥通过SHA1算法进行处理,生成了一个哈希值;

2.取哈希值的后8个字节;

3.把取出来的8个字节顺序倒过来,就是公钥标记了;

  具体代码如下:

1.因为从反编译工具中看到的公钥是以16进制表示的,是320个16进制的组成的字符串,所以首先要把16进制字符串转换成字节数组,代码如下:

public static byte[] HexStringToByte(string hexString)
{
    char[] charList = hexString.ToCharArray();
    byte[] resultList = new byte[charList.Length / 2];
 
    int byteCount = 0;
 
    for (int i = 0; i < charList.Length; i += 2)
    {
        //一个byte相当于两个16进制的数
        byte b = 0x00;
        b |= Convert.ToByte("0x0" + charList[i], 16);
        b <<= 4;//移位操作,左移4位
        b |= Convert.ToByte("0x0" + charList[i + 1],16);
        resultList[byteCount] = b;
        byteCount++;
    }
 
    return resultList;
}

2.对字节数组进行哈希处理,并取出最后的8个字节,反转

public string GetKey(string strSource)
{
    
    string strResult = "";
 
    SHA1Managed sha = new SHA1Managed();
 
    //注意编码UTF8、UTF7、Unicode等的选择 
    byte[] bytResult = sha.ComputeHash(HexStringToByte(strSource));
    byte[] pkt = new byte[8];
 
    // copy the last 8 bytes and reverse it
    Array.Copy(bytResult, bytResult.Length - 8, pkt, 0, 8);
    Array.Reverse(pkt);
 
    //// show the result in hex
    foreach (byte b in pkt)
    {
        strResult = strResult + Convert.ToString(b, 16).PadLeft(2, '0');
    }
    return strResult;
}

3.把320个16进制组成的字符串传入到GetKey方法中,返回的结果就是Public key token了。