简体   繁体   English

C#RSA加密私有解密公共吗?

[英]C# RSA Encrypt Private Decrypt Public?

Here is the problem I am trying to solve. 这是我要解决的问题。 Let's say I was releasing some web software built on ASP.NET MVC and I only wanted the end user to be able to add X users to the system. 假设我发布了一些基于ASP.NET MVC构建的Web软件,而我只希望最终用户能够将X用户添加到系统中。 The software would be hosted on their servers. 该软件将托管在他们的服务器上。

I want to include an encrypted file that when the user tries to add a new user, it goes out and reads from the file an encrypted string. 我想包含一个加密的文件,当用户尝试添加新用户时,该文件将熄灭并从文件中读取一个加密的字符串。 When the website decodes it, the clear text will be the number of allowed users. 网站解码后,明文即为允许的用户数。

What is the best/simplest way on my end to encrypt to generate this string on my end then decode it back to clear text in my application? 最好的/最简单的方法是,在我的一端加密以生成此字符串,然后将其解码回以清除应用程序中的纯文本? Obviously I want to ensure that the end user cannot be spinning up their own encrypted string and just replace mine. 显然,我想确保最终用户不能旋转自己的加密字符串,而只能替换我的。 I don't want to worry about having to try and obfuscate my source so that they would not be able to see how I decode the string. 我不想担心不得不尝试混淆我的源代码,以使他们看不到我如何解码字符串。

Is it possible to encrypt with a private rsa key, then decrypt it with the public one? 是否可以使用私有rsa密钥进行加密,然后使用公共RSA密钥对其进行解密? I haven't had luck with that in the code below: 我在下面的代码中还没有碰运气:

        var rsa = new RSACryptoServiceProvider();

        var pubicKey = rsa.ToXmlString(false);
        var privateKey = rsa.ToXmlString(true);

        var test = "this string needs to be encrypted then decrypted";

        var rsa2 = new RSACryptoServiceProvider();
        rsa2.FromXmlString(privateKey);

        var encryptedBytes = rsa2.Encrypt(Encoding.UTF8.GetBytes(test), false);
        var encryptedString = Convert.ToBase64String(encryptedBytes);

        var rsa3 = new RSACryptoServiceProvider();
        rsa3.FromXmlString(pubicKey);

        encryptedBytes = Convert.FromBase64String(encryptedString);

        var decryptedString = Encoding.UTF8.GetString(rsa3.Decrypt(encryptedBytes,                        false));      

You can use a signature strategy, where the private key is used to generate a signature that verifies that your message is authentic. 您可以使用签名策略,其中私钥用于生成签名,以验证您的消息是真实的。

// Create message and signature on your end
string message = "Here is the license message";

var converter = new ASCIIEncoding();
byte[] plainText = converter.GetBytes(secret);

var rsaWrite = new RSACryptoServiceProvider();
var privateParams = rsaWrite.ExportParameters(true);

// Generate the public key / these can be sent to the user.
var publicParams = rsaWrite.ExportParameters(false);

byte[] signature =
    rsaWrite.SignData(plainText, new SHA1CryptoServiceProvider());

// Verify from the user's side. Note that only the public parameters
// are needed.
var rsaRead = new RSACryptoServiceProvider();
rsaRead.ImportParameters(publicParams);
if (rsaRead.VerifyData(plainText,
                       new SHA1CryptoServiceProvider(),
                       signature))
{
    Console.WriteLine("Verified!");
}
else
{
    Console.WriteLine("NOT verified!");
}

This example was largely copied from Microsoft's site: 此示例主要从Microsoft网站复制而来:

And here is web page that explains the concept: 这是解释该概念的网页:

I think what you are looking for is digital signature. 我认为您正在寻找的是数字签名。 It doesn't matter if the content is encrypted or not, since the user has the (public) key to decrypt it. 内容是否加密无关紧要,因为用户具有(公共)密钥可以解密内容。 All that matters is if the content's source is you. 重要的是内容的来源是您。 Since you have a config file I reckon it is XML, so you are looking for XMLDSIG . 由于您有一个配置文件,我认为它是XML,因此您正在寻找XMLDSIG

You can easily achieve this using the SignedXml class in .Net. 您可以使用.Net中的SignedXml类轻松实现此目的 Then all you need to do is verify the signature when loading the config file. 然后,您需要做的就是在加载配置文件时验证签名。 This method allows you to eaisly use any X509 certificates you may have. 此方法使您可以轻松使用可能拥有的任何X509证书。 You can even embed the public key in the signed file, so the user does not need to install your cert (public key). 您甚至可以将公共密钥嵌入签名文件中,因此用户不需要安装您的证书(公共密钥)。

Your idea is correct, but I wonder about unforeseen consequences. 您的想法是正确的,但我想知道无法预料的后果。

You state they will be running software on their servers, so this means they are hosting a service for themselves. 您声明他们将在其服务器上运行软件,因此这意味着它们将为自己托管服务。 But you also mention this service has to connect out tot he internet to add a user by validating with your server. 但是您还提到,该服务必须与Internet连接才能通过验证服务器来添加用户。 What happens when the internet goes down or they want to have a secure system and a firewall blocks internet access to the servers? 当Internet中断或他们想要一个安全的系统并且防火墙阻止Internet访问服务器时会发生什么? Will they completely lose their ability to function? 他们会完全丧失运作能力吗?

Just giving you a question to ask yourself :p 只是给你一个问题问自己:p

You don't use a public key to 'decrypt' the file. 您不使用公共密钥来“解密”文件。 you can only decrypt the file with the private key. 您只能使用私钥解密文件。

In your case you could store the number of users as well a signature of the data which you create with your private key. 在您的情况下,您可以存储用户数量以及使用私钥创建的数据的签名。

On the clients sever, you use your public key to verify the signature matches the data in the file (number of users) 在客户端服务器上,您使用公共密钥来验证签名与文件中的数据匹配(用户数)

However, it is possible that an advanced user could swap out your public key with their own and sign the file themselves. 但是,高级用户可能会用自己的密钥交换掉您的公钥并自己对文件签名。

As stated in your comment in the question, your approach is using a key from a client and a key from yourself. 如您在问题中的评论所述,您的方法是使用客户的密钥和您自己的密钥。 This will not work, as the prime numbers used in RSA are meant for use with only the corresponding private/public key. 这将不起作用,因为RSA中使用的质数只能用于相应的私钥/公钥。

What you need to do use your two keys and nothing from the client or the client's two keys and nothing of yours. 您需要使用两个密钥,而不必使用客户端的任何密钥,也不需要使用客户端的两个密钥,而无需使用您的密钥。 For example, 例如,

  1. You could sign it using your two keys by encrypting with your private key and allowing the client to decrypt using your public key. 您可以使用私钥加密,并允许客户端使用您的公钥解密,从而使用两个密钥对其进行签名
  2. You could encrypt it using your client's public key and have them decrypt is using their (the client's) private key. 您可以使用客户端的公共密钥对其进行加密,并让他们使用其(客户端的)私钥进行解密。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM