M_Crypto (formerly Blowfish and Bcrypt project)

  1. ‹ Older
  2. 5 years ago

    scott b

    3 Feb 2014 Pre-Release Testers, Xojo Pro local coffee shop

    @Paul M Squirrel!

    I tend to have squirrel moments too.

  3. Norman P

    3 Feb 2014 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...

    @Paul M When working on side projects for fun, I tend to get distracted quite… Squirrel!

    Doug ???

  4. Paul M

    3 Feb 2014 Pre-Release Testers, Xojo Pro Eastern Massachusetts, USA

    @Norman P Doug ???

    or "Dug" :-)

  5. 3 years ago

    Kem T

    9 Mar 2016 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    I just released v.1.1 of the project here:

    https://www.github.com/ktekinay/Blowfish

    This ensures compatibility with 64-bit, introduces Bcrypt.Verify, and a "stress test" that compares the results against PHP to ensure compatibility.

  6. Norman P

    9 Mar 2016 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...

    @Paul M or "Dug" :-)

    Meow !

  7. Kem T

    9 Mar 2016 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    After posting, I found a bug (naturally). The current release is 1.1.1. Same link.

  8. Thomas T

    30 Aug 2016 Pre-Release Testers, Xojo Pro Europe (Germany, Munich)

    On WP, https://en.wikipedia.org/wiki/PBKDF2 , under Alternatives to PBKDF2, it is stated:

    One weakness of PBKDF2 [...] which makes brute-force attacks using ASICs or GPUs relatively cheap. The bcrypt key [...] is slightly stronger [...] while the more modern scrypt key derivation function [...] is more resistant to ASIC and GPU attacks.

    I got a similar answer when asking for password encryption schemes on SO: http://crypto.stackexchange.com/a/39670/38944

    So, bcrypt is apparently better than PBKDF2. Even better would be to use scrypt or Argon2.

    But what has not been explained here is that a Xojo implementation inherently brings along an extra weakness: As the Xojo impl is slower than the original C impl, it means one is forced to use fewer iterations to perform the decryption in an acceptable time. OTOH, a brute force attack can then use the faster C implementation and instantly gains an advantage. I wonder if that's significant at all, though. Perhaps not. It's not that Xojo's code is a million times slower, but perhaps up to 10 times, which is not much of a magnitude to matter much.

    Thoughts?

  9. Thomas T

    30 Aug 2016 Pre-Release Testers, Xojo Pro Europe (Germany, Munich)
    Edited 3 years ago

    Actually... I just only now had a look at Kem's project. As I understand bcrypt, it should have an "interations" (or "cost") parameter, just like PBKDF2 does, see https://en.wikipedia.org/wiki/Bcrypt . But I can't find one in Kem's code. So, this is incomplete, it seems to me.

    Awww, shoot. It's called "rounds". But it means the "cost" parameter. Why rounds? Was that the name used in the original C source? Rounds makes little sense as it implies it'd mean iterations, when, in fact, it means an exponent (iter = 2^cost).

    What surprises me even more, though, is that the "rounds" parameter is used only to be encoded into the $...$ salt string. It's not actually used to control the number of iterations the key is derived.

    Kem, have you ever checked if your code can inter-operarate with OTHER bcrypt implementations (e.g. the openssl cmd can do it, it seems)? Or have you only tested it against itself?

  10. Kem T

    30 Aug 2016 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    I believe "rounds" was taken from the C code, but don't recall now.

    Because we use bcrypt now for hashing, wrote a test that compares the result to that from PHP. It's been run thousands of times with no deviation, but I don't recall if I've changed that parameter during the test. I'll look in a bit.

  11. Thomas T

    30 Aug 2016 Pre-Release Testers, Xojo Pro Europe (Germany, Munich)
    Edited 3 years ago

    Hi Kem, it may be that the PHP code used only a single iteration – then your results would match. Or I somehow overlooked something in the code and it's all correct.

    Here's what you'd have to be able to observe: The higher the "rounds" value, the more time the function takes, exponentially. If time remains constant, then your code is just plain wrong, because that's the whole purpose of the rounds (aka cost) parameter: To for the algo to take more time, so that a brute force has to also take more time for each attempt.

  12. Kem T

    30 Aug 2016 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    I did vary the cost, and the test itself is in the project. The test code:

      //
      // Stress test Bcrypt to make sure the result
      // matches the output from PHP
      //
      
      dim alphabet() as string = split( _
      "abcdefghijklmnopqrstuvwxyz " + _
      "!@#$%^&*()_+" + _
      "=-/.,?><[]{}" + _
      "¡™£¢∞§¶•ªº–≠⁄€‹›fifl‡°·‚—±" + _
      """'" + _
      "œ∑á鮆¥üîøπ¬", _
      "" )
      
      dim passwords() as string
      
      const kMinLetters = 5
      const kMaxLetters = 15
      const kRounds = 50
      
      dim r as new Random
      
      for letterCount as integer = kMinLetters to kMaxLetters
        for round as integer = 1 to kRounds
          dim wordArr() as string
          
          for letterIndex as integer = 1 to letterCount
            dim randomCharIndex as integer = r.InRange( 0, alphabet.Ubound )
            dim char as string = alphabet( randomCharIndex )
            wordArr.Append char
          next letterIndex
          
          
          dim word as string = join( wordArr, "" )
          passwords.Append word
        next round
      next letterCount
      
      const kMinCost = 7
      const kMaxCost = 12
      
      for cost as integer = kMinCost to kMaxCost
        AddToResult "Cost: " + str( cost )
        
        dim salt as string = Bcrypt_MTC.GenerateSalt( cost )
        
        for each pw as string in passwords
          dim myHash as string = Bcrypt_MTC.Bcrypt( pw, salt )
          if not PHPVerify( pw, myHash ) then
            AddToResult "PHP no match: " + pw
          elseif not Bcrypt_MTC.Verify( pw, myHash ) then
            AddToResult "Internal no match: " + pw
          end if
          if UserCancelled then
            AddToResult "Cancelled"
            exit for cost
          end if
        next
        fldResult.Refresh
      next
      
      AddToResult "Bcrypt Stress Test Finished"
      
      return
  13. Kem T

    30 Aug 2016 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    BTW, this runs significantly faster in 64-bit, for what that's worth.

  14. Thomas T

    30 Aug 2016 Pre-Release Testers, Xojo Pro Europe (Germany, Munich)
    Edited 3 years ago

    Okay - false alarm. The code appears to be sound.

    Sorry for that, I should have tested it first. The results show exactly what I claimed should happen: Changing the "rounds" parameter will affect the time the calculation takes. So all seems to be good.

    However, your test code do not seem to test the Bcrypt function that takes a "rounds" instead of a "salt" parameter at all. That's not decent testing, you know. That's part of what made me suspicious: That function doesn't get called and it seems it never passes the rounds parameter further on, so I made the (incorrect) assumption that this isn't right.

    Also, anyone testing your test code as an example will be surprised that one Bcrypt call will take 5-10 seconds (in 32 bit builds). It should be made more clear that they should then use a smaller rounds value to decrease the time. Of course, it'll also downgrade the security a little, but that's still better than annoying your users with a delay of 10s every time they want to log in while your have Bcrypt check their password.

  15. Kem T

    30 Aug 2016 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    Whoa, where do you see 5-10 seconds? And have you compared that to another implementation with the same cost setting to check the time difference?

  16. Thomas T

    30 Aug 2016 Pre-Release Testers, Xojo Pro Europe (Germany, Munich)
    Edited 3 years ago

    I built for 32 bit with 2016r1.1. Though I ran it in the debugger (shouldn't matter, though). On a 2.8 GHz Mac Pro.
    Ran for 7.1s for rounds=10. And twice the time for rounds=11, as expected.

    Update:

    Huh, okay. Running in the debugger DOES affect runtime significantly. Odd. When built for 32 bit, it runs in 0.8s (in debugger now 5.3s). And for 64 bit 0.32s. That's more like it.

  17. Kem T

    30 Aug 2016 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    Thomas, I did all I could think of to optimize this code, including things I would never recommend to anyone else. Perhaps you can spot other areas of improvement.

  18. Thomas T

    30 Aug 2016 Pre-Release Testers, Xojo Pro Europe (Germany, Munich)

    Sorry, I've already spent too much time on this topic, and most of it was even misguided due to my own fault. I have no decided to use the more modern "scrypt", which is open source, so I've just built a dylib that I link to from Xojo. Works fine. The only challenge left will be to port it to Windows later on.

  19. 2 years ago

    Kem T

    19 Sep 2017 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    I just updated this project and changed it over to M_Crypto from Blowfish_MTC. It's available here:

    https://github.com/ktekinay/M_Crypto

    It now includes a native AES encrypter and a handy all-purpose encryption/decryption app in the project. The README has more information.

  20. Kem T

    27 Sep 2017 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    I just released v.2.1. These are the release notes:

    • Refactored to streamline code.
    • Changed NullsWithCount padding to conform to standard. It will now add padding in all cases, even if the block is already the right size. This means the last padding byte can be 0x01, something that wasn't allowed in the previous version. Depadding will still work on something encrypted like that unless you decrypt in blocks and the last block is <= BlockSize.
    • Added the CLI project and reorganized files in general.

    I'm particularly happy with the CLI project. You can now encrypt/decrypt on the command line with a variety of options. From the help:

      mtccrypto - Encrypt/Decrypt/Bcrypt utilty v.1.0
    
    Help:
      -h, --help           Show help
      -x STR, --execute=STR
                           The action to perform [can be: `Encrypt', `E',
                           `Decrypt', `D', `Bcrypt', `B', `Verify-bcrypt',
                           `V']
      --salt=STR           The specific salt to use for Bcrypt in the
                           correct format (testing option not normally used)
      --rounds=INTEGER     The number of rounds to use for Bcrypt if salt
                           is not specified [default 10]
      --against-hash=STR   The hash to verify with Bcrypt
      -e STR, --encrypter=STR
                           Encrypter to use for encrypt/decrypt [can be:
                           `aes-128', `aes-128-cbc', `aes-128-ecb', `aes
                           -192', `aes-192-cbc', `aes-192-ecb', `aes-256',
                           `aes-256-cbc', `aes-256-ecb', `bf', `bf-cbc',
                           `bf-ecb']
      -k STR, --key=STR    The encryption key as plain, hex, or Base64
      --key-file=FILE      The file that contains the key
      --key-stdin          The key has been piped in through StdIn
      -K STR, --key-encoding=STR
                           The encoding of the key [default None] [can be:
                           `None', `N', `Hex', `H', `Base64', `B']
      -H STR, --key-hash=STR
                           The hash to apply to the key [default None] [can
                           be: `None', `N', `MD5', `M', `SHA1', `S1',
                           `SHA256', `S256', `SHA512', `S512']
      -p STR, --padding=STR
                           The padding to use [default PKCS] [can be:
                           `Nulls-Only', `Nulls-With-Count', `PKCS']
      --iv=STR             With CBC encryption, the initial vector as plain or hex
      -D STR, --data-encoding=STR
                           The encoding of the data [default None] [can be:
                           `None', `N', `Hex', `H', `Base64', `B']
      --data-file=FILE     The file that contains the data
      --data-stdin         The data has been piped in through StdIn
      -O STR, --output-encoding=STR
                           Encode the result of encryption/decryption
                           [default None] [can be: `None', `N', `Hex', `H',
                           `Base64', `B']
      --output-file=FILE   The output file that will be overwritten
      --eol                Include an EOL in the output [default TRUE
                           unless --output-file is used]
    
    Notes:
      If data is not given and no file specified, it will be pulled from
      StdIn.
    
      When encrypting/decrypting, if a key is not given it will be
      requested unless the --data-stdin switch is present.
  21. Is it possible to use this implementation with iOS Xojo projects?

    Thanks.

    p.s. It would be great thing, even for Xojo R&D, to add supported platforms tags in text and/or technical documentation.

  22. Newer ›

or Sign Up to reply!