使用RSA密钥保护许可证密钥

时间:2010-03-30 20:22:43

标签: c# rsa digital-signature

已经晚了,我累了,而且可能非常密集......

我编写了一个我需要保护的应用程序,因此它只能在我生成密钥的机器上运行。 我现在正在做的是获取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进行签名/加密,然后将公钥放入app目录并使用它来验证/解密代码?如果我能让签名部分正常工作,我可以删除加密部分。我使用它作为备份来混淆我所关注的许可证代码的来源。

这有什么意义吗? 我是一个彻头彻尾的人吗?

感谢任何人可以帮助我的帮助..

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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