zoukankan      html  css  js  c++  java
  • C#程序集系列09,程序集签名

    在"C#程序集系列08,设置程序集版本"中体验了为程序集设置版本,但对于程序集的安全性来说,还远远不够。本篇体验程序集的签名。

     

    □ 程序集的签名

    →F盘as文件夹下有多个文件
    51
    →在程序集所在文件夹创建密匙
    52
    →打印密匙

    53
    密匙是一堆乱码,这是经过加密了。
    →在密匙的基础上创建公匙Public Key
    54
    →打印公匙Public Key
    55
    注意:这里的public token是public key经过哈希算法而获得的。当程序集被引用,该程序集对外是以public token形式存在的。

    →现在重新编译"C#程序集系列08,设置程序集版本"中的Cow.cs,但这次使用密匙
    56
    →重新编译"C#程序集系列08,设置程序集版本"中的MainClass.cs,引用刚创建的Farm.dll
    57
    →运行MainClass.exe
    58
    →现在模拟一个病毒程序集,首先在F盘的as文件夹中创建CowVirus.cs
    →用记事本打开CowVirus.cs,编写如下,保存

    using System;
    
    using System.Reflection;
    
    [assembly: AssemblyVersion("3.3.3.3")]
    
    public class Cow
    
    {
    
        public static void Moo()
    
        {
    
            Console.WriteLine("我是病毒");
    
        }
    
    }
    

    →编译CowVirus.cs,生成新的Farm.dll,重写原先的Farm.dll,并且在没有私匙的情况下
    59
    →再次运行MainClass.exe
    60

    可见,病毒程序虽然模拟了一个相同名称的程序集,但由于没有签名,该程序集不会得到主程序的认可。

     

    □ Public Token

    如果一个A程序集有public key,且被B程序引用,如果我们反编译B程序,在B程序的IL代码中就可以看到A程序集有一个public token,这个public token是根据A程序集的public key经哈希算法而得到的。

     

    →再次重写Farm.dll,编译Cow.cs文件,并且使用密匙
    61
    →反编译Farm.dll
    62
    来看Farm程序集的清单部分:

    .assembly Farm
    
    {
    
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 
    
      .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
    
                                                                                                                 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
    
      .publickey = (00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00   // .$..............
    
                    00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00   // .$..RSA1........
    
                    49 2C E7 BF EF 82 D2 44 A3 F4 AB 96 27 32 89 A4   // I,.....D....'2..
    
                    77 E6 AD A6 A3 21 62 E3 0A DA 72 9D BA 0A 7C 59   // w....!b...r...|Y
    
                    51 0C F6 63 22 ED E3 50 4B F5 61 E2 1A 7F ED 26   // Q..c"..PK.a....&
    
                    78 BD 1B 99 E7 1C 91 7F 80 E6 3F 9B 1C F0 85 63   // x.........?....c
    
                    58 5D 8B DC 60 41 69 2A F3 E6 EB 9B 42 4D D8 B6   // X]..`Ai*....BM..
    
                    C5 B0 31 47 77 58 C6 53 65 2A B1 90 30 EA 24 EF   // ..1GwX.Se*..0.$.
    
                    2A 1C 92 DD 62 D3 00 F6 F3 CA 0E 24 1C A8 F2 2E   // *...b......$....
    
                    5D D3 06 41 A7 77 EE EB C0 2F 64 83 2A 59 00 AE ) // ]..A.w.../d.*Y..
    
      .hash algorithm 0x00008004
    
      .ver 3:3:3:3
    
    }

    以上,程序集Farm.dll中包含了public key。

    →重新编译MainClass.cs,并且引用Farm.dll程序集,重新生成MainClass.exe
    63
    →运行MainClass.exe
    64
    →反编译MainClass.exe
    65
    →查看到MainClass.exe的IL代码

    .assembly extern mscorlib
    
    {
    
      .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .zV.4..
    
      .ver 4:0:0:0
    
    }
    
    .assembly extern Farm
    
    {
    
      .publickeytoken = (21 64 02 E8 98 B6 AC A9 )                         // !d......
    
      .ver 3:3:3:3
    
    }
    
    .assembly MainClass
    
    {
    
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 
    
      .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
    
                                                                                                                 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
    
      .hash algorithm 0x00008004
    
      .ver 0:0:0:0
    
    }

    以上,在.assembly extern Farm语句块中,.publickeytoken的值,是根据Farm.dll程序集的public key哈希算法后获得的。

     

    总结:
    ○ 通过给程序集签名,即给程序集加密匙,程序集就有了public key,这样会有效防止他人恶意篡改程序集
    ○ 程序集被A程序引用,如果反编译A程序,程序集清单中有一个public token,该值是public key经哈希算法而得到的

     

    “C#程序集系列”包括:

      C#程序集系列01,用记事本编写C#,IL代码,用DOS命令编译程序集,运行程序

      C#程序集系列02,使用记事本查看可执行程序集的IL代码

      C#程序集系列03,引用多个module

      C#程序集系列04,在程序集包含多个module的场景下理解关键字internal

      C#程序集系列05,让程序集包含多个module

      C#程序集系列06,程序集清单,EXE和DLL的区别

      C#程序集系列07,篡改程序集

      C#程序集系列08,设置程序集版本

      C#程序集系列09,程序集签名

      C#程序集系列10,强名称程序集

      C#程序集系列11,全局程序集缓存

      C#程序集系列12,C#编译器和CLR如何找寻程序集

      C#程序集系列13,如何让CLR选择不同版本的程序集

    参考资料:

    http://www.computersciencevideos.org/  created by Jamie King

  • 相关阅读:
    Java中的synchronized以及读写锁
    Java中的HashMap低层实现原理
    AOP
    PageRank算法
    Python基础
    RF创建测试库
    RF-RequestsLibrary
    selenium webdriver
    RF开发关键字(四)
    RF关键字(三)
  • 原文地址:https://www.cnblogs.com/darrenji/p/3970511.html
Copyright © 2011-2022 走看看