我可以使用程序集 PublicKey 来解密使用相应 PrivateKey 加密的字符串吗?
在 .NET 中对程序集进行签名涉及公钥/私钥对。据我所知,.NET 使用 RSA 算法和私钥对程序集进行签名,并使用嵌入的公钥对其进行检查。
我知道如何检索公钥 (Assembly.PublicKey
)。我想知道,该密钥是否可用于解密包含一些用私钥加密的数据的短字符串。
到目前为止我读过的文档(eg)似乎暗示只有相反的方式是可能的:我必须使用公钥进行加密并使用私钥进行解密 - 但我真的不想将其包含在程序集中,是吗?
我想它会没问题,如果我只是签署了字符串。但如何呢?
我有点不知如何开始。有人有代码片段吗?
另外,小字符串的加密/签名最好在 PHP 中进行,因为我想将其卸载到 Web 服务器,而到目前为止我们拥有的只是通用 PHP/MySQL 托管网站。
用例:我正在尝试为我们即将发布给 Beta 测试人员的软件提出一个轻量级许可方案。由于该软件可能是免费软件,因此我们真正想要实现的是
- 知道谁安装了该软件(电子邮件地址),
- 让该软件在给定期限后过期,之后用户将必须获得新的许可证
- 这就像填写表格并等待包含钥匙的自动电子邮件到达一样简单
- 我们正在努力降低旧版本再次出现损害我们声誉/困扰我们的可能性
可能性能够加密元组(到期日、指纹)并在启动时解密,这将构成一个简单的许可模块:应用程序第一次启动时,系统会要求用户提供电子邮件地址、姓名、组织。此信息与某些系统信息(网卡、计算机名称、程序集主要版本和次要版本)的 md5 指纹一起发布到网络服务器。网络服务器通过电子邮件进行答复(检查电子邮件地址的有效性),其中包含元组的加密版本(到期日期、指纹),然后保存到磁盘。启动时,可以对其进行解密并与当前日期和重新生成的指纹进行比较。
编辑:好的,所以我还没有得到问题的所有答案。但看起来 .NET 不会让使用私钥进行加密变得容易(如果可能的话,答案并不真正同意这一点)。
我将采取的路线是这样的(基于我的用例):
- 我将使用私钥来签署许可证。
- 我将使用公钥来验证许可证是否由私钥签名
- 我将针对 PHP 开发人员发布另一个问题,了解如何使用 .NET 密钥(由
sn.exe
生成)来签署一些text - 我并不真正担心用户看到许可证,因为无论如何它都是一个哈希值,并且是根据他已经知道的东西计算出来的。我想要的只是让典型的建筑建筑师在我不知情的情况下复制我的软件变得太困难(记住,该软件将是免费软件 - 我想要的只是一份安装该软件的人的书面记录...... )
非常感谢您的回答。
Signing an assembly in .NET involves a public/private key pair. As far as I can tell from what I've read .NET uses the RSA algorithm and the private key to sign the assembly, checking it with the embedded public key.
I know how to retrieve the public key (Assembly.PublicKey
). I was wondering, if that key could be used to decrypt a short string that contains some data encrypted with the private key.
The docs I've read so far (e.g.) seem to imply that only the other way round is possible: That I would have to use the public key to encrypt and the private key to decrypt - but I don't really want to include that in the assembly, do I.
I guess it would be ok, if I just signed the string. But how?
I'm a bit at a loss how to start this. Does anybody have a code snippet?
Also, encrypting / signing of the small string would ideally happen in PHP, since I want to offload that to a web server and all we have so far is your generic PHP/MySQL hosted website.
Use Case: I'm trying to come up with a lightweight licensing scheme for a software we are about to release to beta testers. Since the software will probably be freeware, all we really want to achieve is
- know who has the software installed (email address)
- let the software expire after a given period, after which the user will have to get a new license
- this is as easy as filling out a form and waiting for an automated email with the key to arrive
- we are trying to reduce the likelyhood of old versions coming back to bite our reputation / haunt us
Being able to encrypt a tuple (expiry date, fingerprint) and decrypt that at startup would make an easy licensing module: The first time the application is started, the user is asked for email address, name, organisation. This information is posted to the webserver along with an md5 fingerprint of some system info (nic, computer name, assembly major and minor version). The webserver answers by email (checks validity of email address) with an encrypted version of the tuple (expiry date, fingerprint) that is then saved to disk. On startup, this can be decrypted and compared with current date and regenerated fingerprint.
EDIT: OK, so I don't have all the answers to my question yet. But it looks like .NET won't make it easy to use the private key for encryption (if that is at all possible, the answers don't really agree on that).
The route I will take is this (based on my use case):
- I will use the private key to sign the license.
- I will use the public key to verify the license was signed by the private key
- I will post another question aimed at PHP devs on how to use the .NET keys (produced by
sn.exe
) to sign some text - I am not really worried about the user seeing the license, as it is a hash anyway and computed from stuff he allready knows. All I want is to make it too hard to be worth any bother for your typical building architect to copy my software without me knowing (remember, the software will be freeware - all I want is a paper trail of who has it installed...)
Thank you very much for your answers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您无法使用公钥解密。那样的话,“公共”的意义就消失了。
(但是,您可以使用私钥对某些内容进行签名,然后使用公钥验证签名。这就是框架使用密钥的目的 - 程序集已签名,公钥用于验证签名。 )
You cannot decrypt using the public key. That way, the whole point of "public" would be lost.
(You might, however, be able to sign something using the private key, then verify the signature using the public key. That's what the framework uses the keys for - the assembly is signed, and the public key is used to verify the signature.)
这可以使用 SignedXml http://msdn.microsoft.com/en- 来完成我们/library/ms229745.aspx。在较低级别,您可以使用 RSAPKCS1SignatureDeformatter 和 RSAPKCS1SignatureFormatter。这些工作原理是加密数据的哈希值,然后将数据与另一端的(解密的)哈希值进行比较。我相信使用散列是因为私钥加密只能处理小数据。不确定是否重用程序集公钥,如果它导致问题,只需使用单独的密钥对。
警告,请查看此内容,因为这些类可能会导致 20 秒挂起! http://www.pcreview.co.uk/forums/thread-3428177。 php
这种方法很容易受到使用 Reflexil 篡改签名验证代码的影响,但这是另一回事。
我写了以下内容,但重读后,我认为您已经明白了:您并不是真正试图加密或隐藏用户的数据,而是想阻止他们创建或篡改许可证。您是对的,可以使用公钥私钥加密算法来实现此目的。这称为使用私钥进行签名(服务器端许可证生成)。并使用公钥验证签名(应用程序中的许可证检查)。我提到这个术语是因为它有助于研究。
This can be done using SignedXml http://msdn.microsoft.com/en-us/library/ms229745.aspx. At a lower level you can prob use RSAPKCS1SignatureDeformatter and RSAPKCS1SignatureFormatter. These work by encrypting a hash of the data then comparing the data with the (decrypted) hash the other end. I believe the hashing is used because private key encryption can only handle small data. Not sure about reusing the assembly public key, if it is causing problems just use a separate key pair.
Word of warning, check out this as these classes can result in 20 second hang ups! http://www.pcreview.co.uk/forums/thread-3428177.php
This approach is vulnerable to the signature verification code being tampered with using Reflexil but that is another matter.
I wrote the following but rereading I think you already got this: You aren't really trying to encrypt or hide data from the user, you want to stop them from creating or tampering the license. You are right that a public private key encryption algorithm can be used for this. This is known as Signing using a private key (server side license generation). And verification of the signature using a public key (license checking in the app). I mention this terminology as it'll help with research.
不在 .NET 中。
在许多传统的公钥加密算法中,例如 RSA,您可以采用两种方式进行加密和解密,通常一种方式称为“加密”,另一种方式称为“签名”,即使您实际上最终得到了两种方式的加密版本。
然而,在 .NET 中,RSA 实现已被削弱,签名时只会生成输入的摘要,而不是完整的处理信息。
似乎对于 RSA 可以做什么和不能做什么存在一些分歧,所以让我编辑我的答案以使其更具体。
我说的是 RSA 数学,而不是任何特定的 RSA 实现。
RSA 数学允许您对两个密钥(私有或公共)中的任何一个进行信息编码,并且编码的数据只能使用两个密钥中的另一个进行解码。
通常,您使用公钥进行编码,加密信息,并使用私钥对其进行解码,解密信息。或者,您获取信息的哈希值,使用私钥对其进行编码,对哈希值进行签名,然后使用公钥对哈希值进行解码,以便比较和验证签名。
典型的实现不允许人们仅通过散列数据来对从私有到公共的数据进行完整编码,但RSA背后的数学完全允许这样做。
Not in .NET.
In many traditional public-key encryption algorithm, like RSA, you can encrypt and decrypt both ways, typically one way is called "encryption" and the other "signing", even though you actually end up with an encrypted version of something both ways.
However, in .NET the RSA implementation has been crippled, and when signing will only produce digests of the input, not the full processed information.
It seems there's some disagreement about what can and cannot be done with RSA, so let me edit my answer to be more specific.
I'm talking about RSA math, not any particular RSA implementation.
RSA math allows you to encode information either of the two keys (private or public), and the encoded data can only be decoded with the other of the two keys.
Typically, you encode with a public key, encrypting the information, and decode it with the private key, decrypting the information. Or, you take a hash of the information, encode it with the private key, signing the hash, and decode the hash with the public key, in order to compare and verify the signature.
Typical implementations does not allow one to do full encoding of data from private to public, only by hashing the data, but the math behind RSA fully allows this.
在RSA中,公钥用于加密,私钥用于解密。你不能使用公钥来解密任何东西......
In RSA Public keys are used for encryption, private keys are used for decryption. You can't use a public key to decrypt anything...
在 RSA 中,公钥和私钥之间的唯一实际区别在于您要保密哪一个。
因此,您可以使用公钥作为加密密钥并使用私钥解密,或者使用私钥作为加密密钥并使用公钥解密。
使用私钥加密用于数字签名(任何人都可以使用公钥解码)。
但正如 @Lasse V. Karlsen 指出的那样,.Net 可能会让事情变得比应有的更加困难......
In RSA the only actual difference between a public key and a private key is which one you keep secret.
So you can use a public key as the encryption key and decrypt with the private key, or use the private key as the encryption key and decrypt with the public key.
Encrypting with the private key is used for digital signatures (anybody can decode with the public key).
But as @Lasse V. Karlsen pointed out, .Net might make it more difficult than it should be...
我认为两个方向都可以用公共密钥加密,用私有密钥解密,用私钥加密。第二个是数字签名的工作方式。
I think both direction are possible encrypt with public and decrypt with private and encrypt with private key. The second is the way how digital signature works.
警告!这个答案是错误的,但我还是要把它留在这里,因为附加的一系列评论是,我认为其他人有足够的兴趣来保留答案。好吧,这让我看起来像个白痴,但这对我来说不是什么新鲜事;)按照你的意愿投票。
公钥可用于: -
它不能用于解密由私钥加密的内容。因此,公钥/私钥系统被称为非对称系统。
Warning! This answer is wrong but I'm going to leave it here none-the-less because the series of comments attached are, I think of sufficient interest to others to keep the answer around. Ok it makes me look like an idiot but thats nothing new to me ;) Vote as you wish.
A public key can be used to:-
It can not be used to decrypt something to encrypted by a private key. Its for this reason that the Public/Private key system is refered to as an Asymetric system.