5

很晚了,我累了,而且可能很密集......

我编写了一个需要保护的应用程序,因此它只能在我为其生成密钥的机器上运行。我现在正在做的是获取 BIOS 序列号并从中生成哈希,然后我使用 XML RSA 私钥对其进行加密。然后我签署 XML 以确保它没有被篡改。我正在尝试打包公钥以解密和验证签名,但每次我尝试以与生成签名的用户不同的用户身份执行代码时,我都会在签名上失败。

我的大部分代码都是根据我找到的示例代码修改的,因为我对 RSA 加密并不像我想的那样熟悉。下面是我正在使用的代码以及我认为我需要使用的代码才能使其正常工作......

任何反馈都将不胜感激,因为此时我完全迷失了我正在使用的原始代码是这样的,只要启动程序的用户与最初签署文档的用户相同,此代码就可以正常工作......

 CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
            cspParams.Flags = CspProviderFlags.UseMachineKeyStore;

            // Create a new RSA signing key and save it in the container. 
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams)
            {
                PersistKeyInCsp = true,
            };

这段代码是我认为我应该做的,但无论我做什么,它都无法验证签名,无论它是同一个用户还是不同的用户......

RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
            //Load the private key from xml file
            XmlDocument xmlPrivateKey = new XmlDocument();
            xmlPrivateKey.Load("KeyPriv.xml");
            rsaKey.FromXmlString(xmlPrivateKey.InnerXml);

我相信这与关键容器名称有关(这里是一个真正的笨蛋,请原谅我)我很确定这是导致它在第一种情况下工作并阻止它在第二种情况……

cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";

有没有办法让我在生成应用程序许可证时使用私钥对 XML 进行签名/加密,然后将公钥放到应用程序目录中并使用它来验证/解密代码?如果我能让签名部分正常工作,我可以放弃加密部分。我用它作为备份来混淆我键入的许可证代码的来源。

这有什么意义吗?我是个彻头彻尾的笨蛋吗?

感谢任何人都可以在这方面给我的任何帮助..

4

2 回答 2

5

我使用此方法使用存储在 xml 文件中的私钥对 xml 文档进行签名,然后将其作为资源嵌入到应用程序 .dll 中。我认为您可能正在为访问密钥库的权限而苦苦挣扎,这也会造成将代码传输到其他服务器等的麻烦。

下面是获取私钥作为嵌入资源并对文档进行签名的代码:(sign是这个方法所在的类的名称,Licensing.Private.Private.xml是默认命名空间+文件夹+文件名的组合资源)

public static void SignDocument(XmlDocument xmldoc)
{
    //Get the XML content from the embedded XML privatekey.
    Stream s = null;
    string xmlkey = string.Empty;
    try
    {
        s = typeof(Sign).Assembly.GetManifestResourceStream("Licensing.Private.Private.xml");

        // Read-in the XML content.
        StreamReader reader = new StreamReader(s);
        xmlkey = reader.ReadToEnd();
        reader.Close();
    }
    catch (Exception e)
    {
        throw new Exception("Error: could not import key:",e);
    }

    // Create an RSA crypto service provider from the embedded
    // XML document resource (the private key).
    RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
    csp.FromXmlString(xmlkey);
    //Creating the XML signing object.
    SignedXml sxml = new SignedXml(xmldoc);
    sxml.SigningKey = csp;

    //Set the canonicalization method for the document.
    sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigCanonicalizationUrl; // No comments.

    //Create an empty reference (not enveloped) for the XPath transformation.
    Reference r = new Reference("");

    //Create the XPath transform and add it to the reference list.
    r.AddTransform(new XmlDsigEnvelopedSignatureTransform(false));

    //Add the reference to the SignedXml object.
    sxml.AddReference(r);

    //Compute the signature.
    sxml.ComputeSignature();

    // Get the signature XML and add it to the document element.
    XmlElement sig = sxml.GetXml();
    xmldoc.DocumentElement.AppendChild(sig);
}

使用以下代码生成 private.xml 和 public.xml 密钥。显然,保持 private.xml 文件的安全。

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
File.WriteAllText(@"C:\privateKey.xml", rsa.ToXmlString(true));  // Private Key
File.WriteAllText(@"C:\publicKey.xml", rsa.ToXmlString(false));  // Public Key
于 2010-03-30T20:38:55.807 回答
0

猜猜,问题是不同的用户无权访问为第一个用户存储的密钥(请注意:我不是密码学专家)。

于 2010-05-14T19:06:58.127 回答