如何使用相同的密钥对来强化程序集并签署文件?

时间:2014-08-06 00:07:52

标签: c# .net encryption

我想使用公钥/私钥对来签署程序集,还要签署程序集将通过USB密钥接收的一些配置设置。

基本原理是程序集将能够使用其中嵌入的公钥来验证其自身的完整性,并在到达时验证设置文件。

我使用sn.exe生成密钥对文件,然后使用.snk文件对程序集进行签名。

然后,在代码中,我使用:

byte[] k = Assembly.GetExecutingAssembly().GetName().GetPublicKey();

访问公钥。

同时,我使用sn.exe -i将密钥对存储在机器商店中。

我的服务器代码使用:

CspParameters cspp = new CspParameters();
cspp.KeyContainerName = "mykey";
cspp.Flags = CspProviderFlags.UseMachineKeyStore;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspp))
  {
    var p = rsa.ExportParameters(true);
    rsa.ImportParameters(p);
    signature = rsa.SignData(toSign, new SHA1CryptoServiceProvider());
  }

对正在发送给远程客户端的文本进行签名。

问题是,在代码片段1中获得的公钥似乎与存储在容器中的公钥不同" mykey"并由代码段2使用。

因此,当我的客户端运行VerifyData方法时,它总是返回false。

签署代码:

public static secobj sign(remobj obj)
{
  // Serialize remote object to string
  var xmlSerializer = new XmlSerializer(typeof(remobj));
  var textWriter = new StringWriter();
  var encoder = new UTF8Encoding();

  xmlSerializer.Serialize(textWriter, obj);
  var toSign = encoder.GetBytes(textWriter.ToString());

  // Sign using stored key in local keystore
  CspParameters cspp = new CspParameters();
  cspp.KeyContainerName = "mykey";
  cspp.Flags = CspProviderFlags.UseMachineKeyStore;
  secobj l = new secobj {D1 = obj.D1, D2 = obj.D2, text = obj.text};
  using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspp))
  {
    var p = rsa.ExportParameters(true);
    rsa.ImportParameters(p);
    l.key = rsa.SignData(toSign, new SHA1CryptoServiceProvider());
  }

  return l;
}

验证码:

public static bool validate(secobj l)
{
  // Obtain the public key from the assembly
  byte[] k = Assembly.GetExecutingAssembly().GetName().GetPublicKey();

  // Set up rsa
  RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
  RSAParameters rsap = rsa.ExportParameters(false);

  rsap.Modulus = k;

  rsa.ImportParameters(rsap);

  // Create remote obj from secobj
  var obj = new remobj {D1 = l.D1, D2 = l.D2, text = l.text};

  // Serialize remote obj to string
  var xmlSerializer = new XmlSerializer(typeof(remobj));
  var textWriter = new StringWriter();
  var encoder = new UTF8Encoding();

  xmlSerializer.Serialize(textWriter, obj);
  var toVerify = encoder.GetBytes(textWriter.ToString());

  return rsa.VerifyData(toVerify, new SHA1CryptoServiceProvider(), l.key);

}

我非常确定本地程序集的签名是否存在问题(我现在在控制台应用程序中将此作为一种测试工具)或者我对Modulous参数的分配。无论如何,签署程序集和验证签名文本之间都会出现问题。

1 个答案:

答案 0 :(得分:0)

有关程序集公钥结构的参考,请参阅structure of the public key of a signed assembly

公钥中没有私钥组件,只有公共模数和公共指数。

使用公钥加密的示例:Sign string using given Public Key