<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi Tobias,</p>
    <p>We has a little more discussion off list about this.</p>
    <p>I would prefer not to change this at the moment.</p>
    <p>In summary and very briefly, my concerns are:</p>
    <p>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.</p>
    <p>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).<br>
    </p>
    <p>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</p>
    <p>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.</p>
    <p>Troy</p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 1/24/20 1:54 PM, Tobias Klein wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:2A7DAF45-6784-49D9-AF44-9C514802B875@tklein.info">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      Hi Troy!<br>
      <br>
      Based on this discussion and Jaak's proposal, would you accept a
      patch for Sword that adds the requested function?<br>
      <br>
      Best regards,<br>
      Tobias<br>
      <br>
      <div class="gmail_quote">Am 15. Januar 2020 20:11:18 MEZ schrieb
        <a class="moz-txt-link-rfc2396E" href="mailto:refdoc@gmx.net">"refdoc@gmx.net"</a> <a class="moz-txt-link-rfc2396E" href="mailto:refdoc@gmx.net">&lt;refdoc@gmx.net&gt;</a>:
        <blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt
          0.8ex; border-left: 1px solid rgb(204, 204, 204);
          padding-left: 1ex;">
          I would second that. It would be trivial to identify a known
          text from the module's printed text and run a brute force<br>
          <br>
          While $key not identified<br>
          If module_decrypted($key, John:1:1) begins with "In the
          beginning"<br>
          Then Found it!<br>
          Else increment $key and restart loop<br>
          <br>
          Peter<br>
          <br>
          Sent from my mobile. Please forgive shortness, typos and weird
          autocorrects.
          <div class="quote" style="line-height: 1.5"><br>
            <br>
            -------- Original Message --------<br>
            Subject: Re: [sword-devel] How to validate a Sword module
            unlock key?<br>
            From: Tobias Klein <contact@tklein.info><br>
              To: SWORD Developers' Collaboration Forum <sword-devel@crosswire.org>,Greg
                Hellings <greg.hellings@gmail.com><br>
                  CC: <br>
                  <br>
                  <br type="attribution">
                  <blockquote class="quote" style="margin:0 0 0
                    .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi!<br>
                    <br>
                    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.<br>
                    What's the conclusion to this discussion?<br>
                    Given the feedback that I saw I would still suggest
                    to move forward with implementing the functionality
                    based on Jaak's proposal.<br>
                    <br>
                    Best regards,<br>
                    Tobias<br>
                    <br>
                    <div class="gmail_quote">Am 13. Januar 2020 19:41:36
                      MEZ schrieb Greg Hellings
                      <a class="moz-txt-link-rfc2396E" href="mailto:greg.hellings@gmail.com">&lt;greg.hellings@gmail.com&gt;</a>:
                      <blockquote class="gmail_quote" style="margin: 0pt
                        0pt 0pt 0.8ex; border-left: 1px solid rgb(204,
                        204, 204); padding-left: 1ex;">
                        <div dir="auto">
                          <div><br>
                            <br>
                            <div class="gmail_quote">
                              <div dir="ltr" class="gmail_attr">On Mon,
                                Jan 13, 2020, 11:28 Troy A. Griffitts
                                &lt;<a
                                  href="mailto:scribe@crosswire.org"
                                  moz-do-not-send="true">scribe@crosswire.org</a>&gt;
                                wrote:<br>
                              </div>
                              <blockquote class="gmail_quote"
                                style="margin:0 0 0 .8ex;border-left:1px
                                #ccc solid;padding-left:1ex">
                                <div>
                                  <p>Hello all,</p>
                                  <p>While the request at face value
                                    seems reasonable, let me explain a
                                    bit of the history behind not having
                                    a method like this.</p>
                                  <p>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.</p>
                                  <p>The reasoning, as you've probably
                                    guessed, is to make it more
                                    difficult to brute force an unlock
                                    key.</p>
                                  <p>This may or may not be important or
                                    effective, but it has been the
                                    policy up until now.</p>
                                  <p>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.</p>
                                </div>
                              </blockquote>
                            </div>
                          </div>
                          <div dir="auto"><br>
                          </div>
                          <div dir="auto">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.</div>
                          <div dir="auto"><br>
                          </div>
                          <div dir="auto">
                            <div class="gmail_quote">
                              <blockquote class="gmail_quote"
                                style="margin:0 0 0 .8ex;border-left:1px
                                #ccc solid;padding-left:1ex">
                                <div>
                                  <p>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.</p>
                                </div>
                              </blockquote>
                            </div>
                          </div>
                          <div dir="auto"><br>
                          </div>
                          <div dir="auto">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.</div>
                          <div dir="auto"><br>
                          </div>
                          <div dir="auto">
                            <div class="gmail_quote">
                              <blockquote class="gmail_quote"
                                style="margin:0 0 0 .8ex;border-left:1px
                                #ccc solid;padding-left:1ex">
                                <div>
                                  <p>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.</p>
                                </div>
                              </blockquote>
                            </div>
                          </div>
                          <div dir="auto"><br>
                          </div>
                          <div dir="auto">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.</div>
                          <div dir="auto"><br>
                          </div>
                          <div dir="auto">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.</div>
                          <div dir="auto"><br>
                          </div>
                          <div dir="auto">--Greg</div>
                          <div dir="auto">
                            <div class="gmail_quote">
                              <blockquote class="gmail_quote"
                                style="margin:0 0 0 .8ex;border-left:1px
                                #ccc solid;padding-left:1ex">
                                <div>
                                  <p>Thoughts?</p>
                                  <p>Troy<br>
                                  </p>
                                  <div>On 1/12/20 11:42 PM, Tobias Klein
                                    wrote:<br>
                                  </div>
                                  <blockquote type="cite">
                                    <p>I like this idea, Jaak! :)</p>
                                    <p>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:</p>
                                    <p><b><font size="+1"><tt>bool
                                            isSwordUnlockKeyValid(std::string
                                            key)</tt></font></b><br>
                                    </p>
                                    <p>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:</p>
                                    <p>- 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.<br>
                                    </p>
                                    <p>- 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).</p>
                                    <p>Best regards,<br>
                                      Tobias<br>
                                    </p>
                                    <div>On 1/12/20 11:46 PM, Jaak
                                      Ristioja wrote:<br>
                                    </div>
                                    <blockquote type="cite">
                                      <pre>Hi!

On 12.01.20 20:53, Greg Hellings wrote:
</pre>
                                      <blockquote type="cite">
                                        <pre>On Sun, Jan 12, 2020 at 10:32 AM Tobias Klein <a href="mailto:contact@tklein.info" target="_blank" rel="noreferrer" moz-do-not-send="true">&lt;contact@tklein.info&gt;</a> wrote:

</pre>
                                        <blockquote type="cite">
                                          <pre>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?

</pre>
                                        </blockquote>
                                        <pre>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.
</pre>
                                      </blockquote>
                                      <pre>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=&lt;Some sufficiently long random ASCII string&gt;
  UnlockKeyVerifyHash=&lt;Hash of field value&gt;

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: <a href="mailto:sword-devel@crosswire.org" target="_blank" rel="noreferrer" moz-do-not-send="true">sword-devel@crosswire.org</a>
<a href="http://www.crosswire.org/mailman/listinfo/sword-devel" target="_blank" rel="noreferrer" moz-do-not-send="true">http://www.crosswire.org/mailman/listinfo/sword-devel</a>
Instructions to unsubscribe/change your settings at above page
</pre>
                                    </blockquote>
                                    <br>
                                    <fieldset></fieldset>
                                    <pre>_______________________________________________
sword-devel mailing list: <a href="mailto:sword-devel@crosswire.org" target="_blank" rel="noreferrer" moz-do-not-send="true">sword-devel@crosswire.org</a>
<a href="http://www.crosswire.org/mailman/listinfo/sword-devel" target="_blank" rel="noreferrer" moz-do-not-send="true">http://www.crosswire.org/mailman/listinfo/sword-devel</a>
Instructions to unsubscribe/change your settings at above page</pre>
                                  </blockquote>
                                </div>
_______________________________________________<br>
                                sword-devel mailing list: <a
                                  href="mailto:sword-devel@crosswire.org"
                                  target="_blank" rel="noreferrer"
                                  moz-do-not-send="true">sword-devel@crosswire.org</a><br>
                                <a
                                  href="http://www.crosswire.org/mailman/listinfo/sword-devel"
                                  rel="noreferrer noreferrer"
                                  target="_blank" moz-do-not-send="true">http://www.crosswire.org/mailman/listinfo/sword-devel</a><br>
                                Instructions to unsubscribe/change your
                                settings at above page</blockquote>
                            </div>
                          </div>
                        </div>
                      </blockquote>
                    </div>
                    <br>
                    -- <br>
                    Message sent from my phone. Please excuse brevity.</blockquote>
                </greg.hellings@gmail.com></sword-devel@crosswire.org></contact@tklein.info></div>
        </blockquote>
      </div>
      <br>
      -- <br>
      Message sent from my phone. Please excuse brevity.
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
sword-devel mailing list: <a class="moz-txt-link-abbreviated" href="mailto:sword-devel@crosswire.org">sword-devel@crosswire.org</a>
<a class="moz-txt-link-freetext" href="http://www.crosswire.org/mailman/listinfo/sword-devel">http://www.crosswire.org/mailman/listinfo/sword-devel</a>
Instructions to unsubscribe/change your settings at above page</pre>
    </blockquote>
  </body>
</html>