Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String#crypt behaving differently that in MRI #1035

Closed
nning opened this Issue Sep 22, 2013 · 19 comments

Comments

Projects
None yet
7 participants
@nning
Copy link

nning commented Sep 22, 2013

I tried getting a Rails project working on JRuby 1.7.4 and a test
regarding password hashes failed. Passwords hashes are created by:

password.crypt('$6$' + salt)

On JRuby 1.7.4 the output looks like:

$ jruby -e 'p "foobar".crypt(%q($6$2mlKb.sZpswpnZlt))'
"$6GFbj3O6XCj2"

On MRI 1.9.3-p448:

$ mri19 -e 'p "foobar".crypt(%q($6$2mlKb.sZpswpnZlt))'
"$6$2mlKb.sZpswpnZlt$yT2dFkrWNtGzxVDgTon7BN2RSh8QRZAznZn.d6ocP/QkAXMTKVXTi0z931ocCYQhvFPzlZPr/OPEmfw8C9pDJ."

And on MRI 2.0.0-247:

$ mri20 -e 'p "foobar".crypt(%q($6$2mlKb.sZpswpnZlt))'
"$6$2mlKb.sZpswpnZlt$yT2dFkrWNtGzxVDgTon7BN2RSh8QRZAznZn.d6ocP/QkAXMTKVXTi0z931ocCYQhvFPzlZPr/OPEmfw8C9pDJ."

I am developing on Arch Linux with glibc 2.18, RUBY_DESCRIPTION in JRuby is:

jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on OpenJDK 64-Bit Server VM 1.7.0_40-b31 +indy [linux-amd64]
@nning

This comment has been minimized.

Copy link
Author

nning commented Sep 22, 2013

I found this posting on stackoverflow.com, which is possibly useful:
http://stackoverflow.com/questions/9062742/crypt3-6-password-hash-algorithm-based-on-sha-512-in-java

@r4um

This comment has been minimized.

Copy link

r4um commented Dec 14, 2013

One can use Crypt from apache commons codec library as a work around.

if RUBY_PLATFORM == "java"
  require  'commons-codec-1.8.jar'

  class String
    def crypt(salt)
      org.apache.commons.codec.digest.Crypt.crypt(self.to_java_bytes, salt)
    end
  end
end

nning added a commit to nning/moeil that referenced this issue Dec 14, 2013

@nning

This comment has been minimized.

Copy link
Author

nning commented Dec 14, 2013

Thanks very much for the work-around, @r4um.

@tthef

This comment has been minimized.

Copy link

tthef commented Oct 27, 2014

Stil broken in 1.7.16.

@cprice404

This comment has been minimized.

Copy link
Contributor

cprice404 commented Nov 26, 2014

Had some users hit this recently as well.

@elyscape

This comment has been minimized.

Copy link

elyscape commented Nov 30, 2014

This continues to be an issue. Mainline Ruby supports standard DES hashes, MD5 hashes ($1$), SHA-256 hashes ($5$), and SHA-512 hashes ($6$) on all several platforms. Considering that DES is incredibly weak and should not be used by anyone nowadays, the fact that JRuby 's String#crypt implementation only supports it is rather disconcerting.

Edit: It turns out that mainline Ruby supports whatever the underlying system's implementation of crypt(3) supports, which in the case of the vast majority of Linux distros is MD5, SHA-256, and SHA-512. OS X and probably AIX are DES only, Solaris is extensible (read: complicated), FreeBSD is MD5, SHA-256/512, NT-Hash, and Blowfish, and OpenBSD is Blowfish and maybe something else.

@enebo enebo added this to the JRuby 1.7.17 milestone Dec 1, 2014

@tduehr

This comment has been minimized.

Copy link
Contributor

tduehr commented Dec 4, 2014

On OSX, I get the jruby 1.7.4 result for all MRI versions I have 1.8.7, 1.9.3, 2.0.0 and 2.1.5.

@enebo

This comment has been minimized.

Copy link
Member

enebo commented Dec 4, 2014

@tduehr yeah so on MacOS it appears it only supports DES. On most (if not all?) modern Linuxes it uses libcrypt which allows these magic salt strings to select the sort of fingerprint you want to use. jruby 1.7.17 will have support on linux but I am hoping to know which other unixy systems use libcrypt by default.

If people can chime in which other OSes that use libcrypt I will update jnr-posix to properly bind to the underlying native crypt.

As an explanation, up to this point JRuby implemented DES crypt in Java. We/I did not even know that libcrypt allowed other signatures (although I am hardly surprised that noone uses DES anymore). I just figured some other C function existed for those fingerprint types.

@elyscape

This comment has been minimized.

Copy link

elyscape commented Dec 5, 2014

It looks like Ruby uses the native crypt(3) implementation on pretty much all systems. System that don't have an implementation of crypt(3) pretty much use a basic implementation identical to that currently provided by JRuby. It looks like the set of systems that don't have one is: Windows. Going down the list of jnr-posix's supported OSes, I'm seeing implementations of crypt(3) (or at least evidence of the existence thereof) for AIX, FreeBSD, Linux, Darwin/OS X, OpenBSD, and Solaris. It's part of the POSIX spec.

@enebo

This comment has been minimized.

Copy link
Member

enebo commented Dec 5, 2014

@elyscape just to clarify you are just saying a native call to crypt but not specifically that all systems are using the same/similar libcrypt linux does right? Because on MacOS I do not see any of the magic salt support for different fingerprint types (nor libcrypt). crypt 3 C (the older DES system has been on all unix variants for as long as I can remember (early eighties)). I am sure it goes back to the genesis of Unix itself.

The change I made to JRuby this week will call out to the native impl which I think is behaving like MRI. My only reservation to the change is on some systems I need to essentially do the equivalent of (-lcrypt) and others it seems to be part of libc. Without trying each one I don't know which ones will fail to load crypt. My previous comment was specifically about this difference and not about crypt existing at all.

@tthef

This comment has been minimized.

Copy link

tthef commented Dec 5, 2014

The change I made to JRuby this week will call out to the native impl which I think is behaving like MRI.

Thanks, this will resolve this issue, i.e., allow for swithcing between JRuby and MRI, and to interoperate with other system components.

Re the extra types, IIRC, these are glibc extensions, they are not part of the POSIX crypt() function, but I don't think there would be much gained by supplementing the native functionality. At least for me, the biggest problem here is interoperability with the base system.

@elyscape

This comment has been minimized.

Copy link

elyscape commented Dec 5, 2014

@enebo: Indeed. I can look into which systems have it as part of libc vs which have it as part of libcrypt in a few hours.

@enebo

This comment has been minimized.

Copy link
Member

enebo commented Dec 5, 2014

@elyscape cool. thanks in advance.

@elyscape

This comment has been minimized.

Copy link

elyscape commented Dec 6, 2014

@enebo:

FreeBSD: libcrypt
Linux: libcrypt
Darwin/OS X: libsystem_c (or just libsystem, if you're able to bind to that)
OpenBSD: libc
Solaris: libc

As for AIX, well:

I DUNNO LOL

(Sorry, I don't have a good way to get information on AIX)

@nning

This comment has been minimized.

Copy link
Author

nning commented Dec 6, 2014

I tried on AIX 5.2 and it uses crypt from libc (which not surprisingly only supports DES).

@enebo

This comment has been minimized.

Copy link
Member

enebo commented Dec 6, 2014

@nning It sort of looks like there is some service provider api for crypt in AIX 7.1 but knowing IBM I am sure that can be anywhere :)

@elyscape cool thanks.

I have been wondering if I should change jnr-ffi to be able to optionally load libraries and not completely link fail if one of them doesn't exist (while still having a mandatory load API). For jnr-posix, I can imagine on a small custom linux env someone will compile _XOPEN or use busybox or ??? and not provide libcrypt. In how we have jnr-posix implemented now then no native functionality will load if libcrypt is missing. But I guess that does not need to hold up 1.7.17 so long as we hit the vast majority of cases.

@elyscape

This comment has been minimized.

Copy link

elyscape commented Dec 6, 2014

For whatever it's worth, on Linux, it looks like libcrypt is provided by glibc, just as a separate .so file for whatever reason. I have no idea if that matters for that, though.

enebo added a commit that referenced this issue Dec 8, 2014

@enebo

This comment has been minimized.

Copy link
Member

enebo commented Dec 8, 2014

Well native crypt here we come....I am hoping we got a reasonable default list for libcrypt folks. If people run into additional problems with new native crypt impl then please open a new issue. This one is done.

@enebo enebo closed this Dec 8, 2014

@elyscape

This comment has been minimized.

Copy link

elyscape commented Dec 8, 2014

Thanks for your work on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.