[sword-devel] How to validate a Sword module unlock key?

Troy A. Griffitts scribe at crosswire.org
Sat Feb 1 14:33:03 MST 2020


Hi Tobias,

We has a little more discussion off list about this.

I would prefer not to change this at the moment.

In summary and very briefly, my concerns are:

1) BEFORE INSTALLATION: I don't think there is enough advantage to
verifying the key before install to warrant moving a hash to the conf
while and putting that burden on the module writers and risk
inconsistencies.  Sure, it would work, but why do we really want to
allow checking before module install?  In the normal use case, the user
will need to install the module anyway if they have a valid key, so we
would only be benefiting users with invalid keys.

I suspect, for you, this might cause additional hassles because you are
doing something we don't recommend or support: extracting module data
from our format and placing it in your own storage format for your
application.  I would continue to suggest you access SWORD data directly
from SWORD modules, on demand, as all of our other applications, instead
of converting all the data to your own format (which has more issues for
copyrighted and locked modules).

2) USER VERIFICATION: We've had this same policy in place for 30+ years
to involve the user to verify the key and have had no complaints.  Some
think (with good logic) that if we use a large enough unlock key, the
computational power to brute force the key will be larger than
practical; even so, computational power and parallel computer improves
and I believe it is still best practice to attempt to involve the user
in verifying the success of an unlock attempt.  There are things we can
do to improve the current mechanism: support a new conf entry which
recommends which module index key to use to check: e.g., 
CipherVerifyKey=Jn.3.16

I don't mean to be difficult, and I realize it would make your life
easier if there was simply an isCipherKeyValid method, and I want to
give you everything I can to make your life easier, but I really think
changing this now has disadvantages which outweigh the advantages.

Troy


On 1/24/20 1:54 PM, Tobias Klein wrote:
> Hi Troy!
>
> Based on this discussion and Jaak's proposal, would you accept a patch
> for Sword that adds the requested function?
>
> Best regards,
> Tobias
>
> Am 15. Januar 2020 20:11:18 MEZ schrieb "refdoc at gmx.net"
> <refdoc at gmx.net>:
>
>     I would second that. It would be trivial to identify a known text
>     from the module's printed text and run a brute force
>
>     While $key not identified
>     If module_decrypted($key, John:1:1) begins with "In the beginning"
>     Then Found it!
>     Else increment $key and restart loop
>
>     Peter
>
>     Sent from my mobile. Please forgive shortness, typos and weird
>     autocorrects.
>
>
>     -------- Original Message --------
>     Subject: Re: [sword-devel] How to validate a Sword module unlock key?
>     From: Tobias Klein
>     To: SWORD Developers' Collaboration Forum ,Greg Hellings
>     CC:
>
>
>         Hi!
>
>         As has been said before, if somebody really wants to crack an
>         unlock key there are still ways to do that ... so, not having
>         the validation function is then more a lack of usability than
>         actual security.
>         What's the conclusion to this discussion?
>         Given the feedback that I saw I would still suggest to move
>         forward with implementing the functionality based on Jaak's
>         proposal.
>
>         Best regards,
>         Tobias
>
>         Am 13. Januar 2020 19:41:36 MEZ schrieb Greg Hellings
>         <greg.hellings at gmail.com>:
>
>
>
>             On Mon, Jan 13, 2020, 11:28 Troy A. Griffitts
>             <scribe at crosswire.org <mailto:scribe at crosswire.org>> wrote:
>
>                 Hello all,
>
>                 While the request at face value seems reasonable, let
>                 me explain a bit of the history behind not having a
>                 method like this.
>
>                 The way we've recommended in the past for frontends to
>                 build a UI interface for unlocking is to show some
>                 entry in the Bible to the user after deciphering and
>                 ask them if it looks OK.  This might seem kludgy, but
>                 it has the same effect as one of those stupid
>                 captchas-- it require human interaction upon each
>                 decipher confirmation.
>
>                 The reasoning, as you've probably guessed, is to make
>                 it more difficult to brute force an unlock key.
>
>                 This may or may not be important or effective, but it
>                 has been the policy up until now.
>
>                 Practically, what happens these days is that
>                 deciphering has been relocated to before
>                 decompression, and most enciphered modules use
>                 compression, so the end result is that that the
>                 decompression filter will throw a 'corrupt data during
>                 decompression' error and return a 0 length entry--
>                 which can be used for brute force key guessing.
>
>
>             The last time I looked into this, it wasn't just practice.
>             Enciphering just plain didn't work on uncompressed
>             modules. But that was a while ago.
>
>                 So, we're in a state where we don't officially provide
>                 a means to programmatically test an unlock key (for
>                 reasons stated above), but in practice, an empty
>                 buffer returned for, say John.3.16, would give a
>                 reasonable check for an invalid unlock key, or a check
>                 for a valid UTF-8 stream would also be a reasonable
>                 programmatic check.
>
>
>             What about a module like LXX or WLC? I realize those
>             aren't under lock and key, but they're informative that
>             checking for zero length in a particular reference isn't
>             foolhardy. Conversely if it's Genesis 1:1, what about
>             NA28? Particularly of note in commentary modules which
>             could be limited to one book, alone.
>
>                 So, while in principle, I believe it's a good thing to
>                 force user input into unlock confirmation to
>                 discourage brute force guessing, we don't do a good
>                 job with the implementation right now.
>
>
>             Being a programmatic API, I'm not sure we can provide
>             anything to prevent brute force attacks. If I know even a
>             single word of any reference in the work, it becomes
>             trivial to attack by just searching for the word's
>             presence in the resulting output. As long as we are using
>             a cryptographic algorithm that is strong against known
>             plain text attacks, we can leave attacks up to the field
>             of crypt analysis and be happy that we've done our due
>             diligence.
>
>             Jaak's proposal is reasonable and prevents known plain
>             text attacks by resorting to a hash, but it makes
>             maintaining the config file more of a pain. Storing the
>             text in a module file field solves the maintenance problem
>             with the conf file but could cause problems with existing
>             content, depending on how exactly the file format is laid
>             out - an area you're the expert in.
>
>             --Greg
>
>                 Thoughts?
>
>                 Troy
>
>                 On 1/12/20 11:42 PM, Tobias Klein wrote:
>>
>>                 I like this idea, Jaak! :)
>>
>>                 Can we implement this in the Sword engine with the
>>                 next release that also delivers the "individualized
>>                 unlock key function"? Ideally directly with a
>>                 convenient API function that has the purpose to
>>                 validate a given unlock key, with a signature like this:
>>
>>                 *bool isSwordUnlockKeyValid(std::string key)*
>>
>>                 In my view, having a mechanism for validating the
>>                 unlock key is essential for having a professional
>>                 unlock frontend. Without the availability of such a
>>                 mechanism I see the following issues:
>>
>>                 - Users need to go through full installation of a
>>                 module before knowing that the unlock key they
>>                 entered works. This is a rather lengthy feedback loop.
>>
>>                 - Since there is a possibility for input errors when
>>                 entering the key, the frontend must provide extra
>>                 functions to "correct the key" after the installation
>>                 has already happened (this wouldn't be necessary with
>>                 a validation function).
>>
>>                 Best regards,
>>                 Tobias
>>
>>                 On 1/12/20 11:46 PM, Jaak Ristioja wrote:
>>>                 Hi!
>>>
>>>                 On 12.01.20 20:53, Greg Hellings wrote:
>>>>                 On Sun, Jan 12, 2020 at 10:32 AM Tobias Klein <contact at tklein.info> <mailto:contact at tklein.info> wrote:
>>>>
>>>>>                 Hi,
>>>>>
>>>>>                 I'm adding Sword module unlock support to Ezra Project and I've been
>>>>>                 wondering how you would validate a given unlock key?
>>>>>
>>>>>                 Basically the dialog for entering the unlock key is shown when a locked
>>>>>                 module is selected for installation. Before going through the effort of
>>>>>                 installing a module I would like to make sure that the given unlock key
>>>>>                 actually works with the selected module. Is there something in the SWORD
>>>>>                 API that supports the validation of the unlock key entered by the user?
>>>>>
>>>>                 The last time this came up, I believe the answer was that you just have to
>>>>                 try it and display it to the user and they have to decide if the results
>>>>                 are human readable.
>>>>
>>>>                 It would be possible to include a field in modules with a known-good value,
>>>>                 then the API could test if that value matched what was expected when it was
>>>>                 decrypted. Unless that functionality already exists, I don't know of any
>>>>                 other way you could accomplish this.
>>>                 I've thought about this many times myself and as far as I know Greg is
>>>                 right that there is currently no other way besides trial and error to
>>>                 verify the unlock key.
>>>
>>>                 Greg: Do I understand you correctly, that there would need to be an
>>>                 extra field in every such module, and extra logic must be added to SWORD
>>>                 so that this extra field does not show up in frontends? If this is so,
>>>                 it might slightly break compatiblity of modules with older versions of
>>>                 SWORD which do not contain such enhancements.
>>>
>>>                 As an alternative, I suggest for consideration the following approach:
>>>
>>>
>>>                 Add in the module configuration file the two extra pieces of
>>>                 information (presented here as two configuration options with bad names):
>>>
>>>                   UnlockKeyVerifyValue=<Some sufficiently long random ASCII string>
>>>                   UnlockKeyVerifyHash=<Hash of field value>
>>>
>>>                 When a newer version of SWORD detects these configuration options in the
>>>                 module configuration, it can verify the unlock key using the following
>>>                 algorithm:
>>>
>>>                   1) Decrypt the value of the UnlockKeyVerifyValue configuration option
>>>                 (after whitespace trimming) with the unlock key
>>>                   2) Verify that the hash of the value decrypted in step 1 matches the
>>>                 value of the UnlockKeyVerifyHash configuration option.
>>>
>>>
>>>                 Pros:
>>>                  * Modules can easily be amended by adding new entries to their
>>>                 configuration files.
>>>                  * No extra field in the module text is needed, so modules amended with
>>>                 these configuration options will continue to work with older versions of
>>>                 SWORD.
>>>                  * Anyone with the key can generate this verification information.
>>>                  * Only access to the module configuration file is needed to verify the
>>>                 unlock key, so no expensive seeking/reading/parsing the encrypted module
>>>                 content is necessary.
>>>                  * Doesn't too leak much about the key.
>>>
>>>                 Cons:
>>>                  * A hash function must be implemented, but I think this would not need
>>>                 to be cryptographically secure, but would act more like checksum, so
>>>                 even something as simple as CRC-32 might do.
>>>
>>>
>>>                 Notes:
>>>                  * Another alternative would be to use a ciphertext/plaintext pair
>>>                 instead so that no checksum/has must be implemented at all, but this
>>>                 might potentially leak too much about the key, and will likely require
>>>                 the configuration options to include binary values (i.e.
>>>                 escaping/encoding would be needed).
>>>                  * Another alternative would be to decrypt and verify a field from the
>>>                 encrypted module itself, but reading the ciphertext from the module file
>>>                 might be a more expensive operation.
>>>
>>>
>>>                 Hope this helps.
>>>
>>>
>>>                 Best regards,
>>>                 J
>>>
>>>                 _______________________________________________
>>>                 sword-devel mailing list: sword-devel at crosswire.org <mailto:sword-devel at crosswire.org>
>>>                 http://www.crosswire.org/mailman/listinfo/sword-devel
>>>                 Instructions to unsubscribe/change your settings at above page
>>
>>                 _______________________________________________
>>                 sword-devel mailing list: sword-devel at crosswire.org <mailto:sword-devel at crosswire.org>
>>                 http://www.crosswire.org/mailman/listinfo/sword-devel
>>                 Instructions to unsubscribe/change your settings at above page
>                 _______________________________________________
>                 sword-devel mailing list: sword-devel at crosswire.org
>                 <mailto:sword-devel at crosswire.org>
>                 http://www.crosswire.org/mailman/listinfo/sword-devel
>                 Instructions to unsubscribe/change your settings at
>                 above page
>
>
>         -- 
>         Message sent from my phone. Please excuse brevity.
>
>
> -- 
> Message sent from my phone. Please excuse brevity.
>
> _______________________________________________
> sword-devel mailing list: sword-devel at crosswire.org
> http://www.crosswire.org/mailman/listinfo/sword-devel
> Instructions to unsubscribe/change your settings at above page
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.crosswire.org/pipermail/sword-devel/attachments/20200201/f67000e7/attachment-0001.html>


More information about the sword-devel mailing list