Product Keys using Partial Key Verification for Go

blov · · 854 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p><a href="http://gopkg.in/mwmahlberg/pkv.v1">http://gopkg.in/mwmahlberg/pkv.v1</a></p> <p>I came across the need to have a simple product key management for Go. Since I did not find a proper solution, I did a bit of research and found <a href="http://www.brandonstaggs.com/2007/07/26/implementing-a-partial-serial-number-verification-system-in-delphi/">Brandon Staggs&#39; Partial Key Verification</a>. This is the first implementation and I would like to hear critique, suggestions, issues and alike.</p> <hr/>**评论:**<br/><br/>TheMerovius: <pre><p>I never understood why these people don&#39;t just use public key crypto. Just sign a short random string with a private key and do the verification via checking if the signature matches. Tada, unfakeable serial numbers (modulo, of course, the problem of reuse, but that is either impossible to solve anyway, or the solution is the same as for regular serial numbers).</p></pre>tophermck: <pre><p>A UUID v3 would allow you to use the signed string as the seed and create a key that looks similar to a traditional license key and it would be deterministic.</p></pre>mwmahlberg: <pre><p>Yes, but how would you check the key is valid and was issued by <em>you</em>? You&#39;d either have to include <strong>all</strong> valid keys into your software or check them remotely each time.</p></pre>mwmahlberg: <pre><p>One of the key features of PKV is that it is easy to revoke product keys because both for business reasons (customer changed his mind) or security reasons (evil customer leaked product key).</p> <p>The problem with using asymmetric crypto is that you would have to <em>externally</em> verify that the public key still is valid in order to make sure the product key is still valid to be as unbreakable as you assert. Since if the private key was leaked, you have to find a way to invalidate all product keys generated with it. That check, in strict 3-tier architectures is not allowed from tier 2 and tier 3. Yes, you can include the keys to be revoked into your software (which might add up if you want to revoke say 5k product keys, whereas including a blacklisted PKV key needs only a uint32), but this would require additional checking logic, too. Which is already implemented in PKV.</p> <p>But let us set that aside for a moment and assume that external checks are allowed and we already have them implemented. Let us further assume you want to have multiple versions, and the old product keys should not be valid for a newer version and keys could be blacklisted. With async crypto, if done correctly, that would require you to manage multiple public and private keys, basically forcing you to set up a whole PKI with revocation lists etc.</p> <p>With PKV, you&#39;d only need to make sure that you are connected to a correct server via TLS to load the blacklisted keys for the current version. That can be easily achieved with a single call to <a href="https://golang.org/pkg/crypto/tls/#Conn.VerifyHostname" rel="nofollow">&#34;crypto/tls&#34;&#39;s (c *Conn) VerifyHostname(host string)</a>, making the management as easy as having a file with blacklisted keys per release stored on a TLS secured server, as compared to running a whole PKI.</p></pre>TheMerovius: <pre><blockquote> <p>One of the key features of PKV is that it is easy to revoke product keys because both for business reasons (customer changed his mind) or security reasons (evil customer leaked product key).</p> </blockquote> <p>I don&#39;t see how this is at all easier with PKV than with my scheme (let&#39;s call it Signed Product Keys -- SPK). I would claim it is probably even harder. You would somehow need to transmit the information about the revoked key anyway, in my scheme you can do that with, like, a couple of bytes of the signed data (which could just be sequential integers). Doesn&#39;t get any easier than this.</p> <blockquote> <p>The problem with using asymmetric crypto is that you would have to externally verify that the public key still is valid in order to make sure the product key is still valid to be as unbreakable as you assert. Since if the private key was leaked, you have to find a way to invalidate all product keys generated with it.</p> </blockquote> <p>Why do you see the private key being leaked as more likely than your algorithm and inputs being leaked which would give the same ability to crackers? This sounds like an unfair asymmetry in assumptions to me. In an abstract way: In every possible solution there is an algorithm with certain inputs and given both, arbitrary many keys can be generated (by definition, because that&#39;s what you are doing). There is no difference in how likely this is in different solutions, so this scenario can not be used to argue in favor or against a certain solution.</p> <blockquote> <p>(which might add up if you want to revoke say 5k product keys, whereas including a blacklisted PKV key needs only a uint32)</p> </blockquote> <p>A blacklisted SPK only takes up exactly as many bits as you need to encode it&#39;s ID. A uint32 is probably completely safe (it certainly is, if it&#39;s safe for PKV). Again, there is no asymmetry here: If you have N different keys that you want to blacklist individually, you need at least log₂(N) bits to distinguish them (from an information theoretic point of view) in both schemes. If you just sign this log₂(N)-bit identifier and use the signed thing as a product key, you need to transmit (at whatever time and in whatever way) at least log₂(N) bits for each blacklisted keys, which is the minimum (also for PKV, as I said, from an information theoretical point of view), so this is not a disadvantage.</p> <blockquote> <p>but this would require additional checking logic, too</p> </blockquote> <p>Yes, the checking is a lookup in a sorted list (or some other implementation of a set with lookup, like a hashtable). That&#39;s about 3 lines of code in any language, at most, and takes pretty much no time at all for all reasonable sizes of the list of revocations. And again, I claim, that this is pretty much the theoretical minimum, as you <em>somehow</em> need to check your key against membership in some revocation set in every solution that allows revocation.</p> <blockquote> <p>With async crypto, if done correctly, that would require you to manage multiple public and private keys, basically forcing you to set up a whole PKI with revocation lists etc.</p> </blockquote> <p>I disagree. For example, if you sign sequential integers, you simply need to include a cutoff-point per version into your code. Or just include the version number in the signed data and check against that. One Keypair, same power, negligible overhead. And, also here, there is no difference between the solution, as you need to <em>somehow</em> include this information and whatever much information you need for that you can just include in both cases at exactly the same time.</p> <p>I am very confident that there are no serious disadvantages to SPKs, to the point where I would be happy to write down the appropriate protocols to get a strictly better feature set than PKV. Plus the trust, that what you are relying on are actual algorithms designed for security and battle-tested by hundreds of researchers around the world.</p></pre>TheMerovius: <pre><p>Indeed, <a href="https://docs.google.com/document/d/1BGd5jmp5iVqntaBGX_oU9Q_Xre2q9T1yjfje49LTZNY/edit?usp=sharing" rel="nofollow">I just did the writeup</a>. Note that it is written relatively hastily, so it might contain minor inaccuracies.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

854 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传