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

libargon2.dll not found #2

Closed
jwbats opened this issue Aug 26, 2016 · 20 comments
Closed

libargon2.dll not found #2

jwbats opened this issue Aug 26, 2016 · 20 comments

Comments

@jwbats
Copy link

jwbats commented Aug 26, 2016

My solution contains one web project and multiple class libraries. I've set all my projects to x64.

The project runs successfully on either iis express 64 bits or iis local 64 bits.

When I hit this package's methods, I still get this error. What can I do to solve it?

@jwbats jwbats closed this as completed Aug 26, 2016
@jwbats jwbats reopened this Aug 26, 2016
@alipha
Copy link
Owner

alipha commented Aug 26, 2016

jwbats,

I'm assuming you're using the Liphsoft.Crypto.Argon2 1.0.3 nuget package ( https://www.nuget.org/packages/Liphsoft.Crypto.Argon2/ )

When you deploy, the destination directory should contain a bin\ directory and inside it should be Liphsoft.Crypto.Argon2.dll and libargon2.dll. If Liphsoft.Crypto.Argon2.dll is there but libargon2.dll isn't, then for some reason my After Build step isn't executing correctly. What version of visual studio are you using? In your build output, do you see the message -- Liphsoft.CryptoArgon2.targets: Copying files from $(MSBuildThisFileDirectory)..\Argon2\x86\ to $(TargetDir) being displayed?

You could manually copy the libargon2.dll from YOUR_SOLUTION\packages\Liphsoft.Crypto.Argon2.1.0.3\Argon2\x64\libargon2.dll to the bin\ folder with the rest of the dlls, or add a build step yourself, just to get it working.

@jwbats
Copy link
Author

jwbats commented Aug 26, 2016

The libargon2.dll file ends up in the debug directory of the class library that wants to execute your code.

I am getting the following:

An exception of type 'System.DllNotFoundException' occurred in Liphsoft.Crypto.Argon2.dll but was not handled in user code

Additional information: Unable to load DLL 'libargon2.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

@pit123
Copy link

pit123 commented Sep 21, 2016

I'm having the same issue, even with the lastest update. The dll is in the Debug folder.
The program runs, but when it reach the hast part it says:

An unhandled exception of type 'System.DllNotFoundException' occurred in Liphsoft.Crypto.Argon2.dll

Additional information: Unable to load DLL 'libargon2.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

@alipha
Copy link
Owner

alipha commented Sep 21, 2016

What version of visual studio are you using? I tested on VS 2013 and 2015 and worked fine for me. Are you doing anything with custom build steps or build tools?

@jwbats
Copy link
Author

jwbats commented Sep 21, 2016

I'm not using any custom build steps or build tools in VS2015. I've tried
using it in my WebAPI2 project. It has been set to x64 per the
instructions. This also causes VS2015 to no longer create Debug and Release
folders for some reason. Rather, it places my build in the bin folder.

It still won't work for me, unfortunately. I'm disappointed that I'm
basically forced to use a sub par hashing algo (sha512 in my case), because
decent hashing algos aren't yet well enough supported in .NET. I would
really like for this to work. If only there were a native implementation
that installs under the latest .NET version. But with the extremely low
number of downloads for the available Argon2 Nuget packages, I don't think
anybody is going to maintain them.

Alipha, let's say I build a project with your Liphsoft Argon2 package and
it doesn't work. Can I send it over so you can have a look at it to see
what's the matter?

On Wed, Sep 21, 2016 at 9:13 PM, Kevin Spinar notifications@github.com
wrote:

What version of visual studio are you using? I tested on VS 2013 and 2015
and worked fine for me. Are you doing anything with custom build steps or
build tools?


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
#2 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AL9zgP_LB5JvV7q0HVIk0JvEgOLXww1Dks5qsYH2gaJpZM4JuJE4
.

@alipha
Copy link
Owner

alipha commented Sep 28, 2016

@jwbats, you said that libargon2.dll is in the Debug folder but then you said your build is in the bin folder--is the libargon2.dll not with the rest of the dlls from your build? If so, that is probably the problem. They should all be in the same folder. I think that might happen if your solution platform doesn't match your project platforms.

When you open up the configuration manager, make sure that the "Active solution platform" dropdown in the top right is set to x64 and that all the projects in the grid below have the Platform also set to x64. If there's a mismatch, then that could be the problem.

You may also try adding a new platform for x86 in the configuration manager. In the solution platform dropdown, you should be able to select <New...> and select x86 in the new window that pops up. Again, make sure that all the projects are also set to x86.

Honestly, I did most of my testing with console applications. I did some testing today with creating a Web API application. I ran into issues when setting the configuration to x64--the Visual Studio debugger doesn't appear to support x64, so then I had to set my project to use local IIS, and then I had issues with IIS not having permission to access the libargon2.dll, and it was just a mess. Using x86 instead was a lot smoother, so I would recommend trying that.

I hope that helps. Yeah, you can send me your code if you're still having problems and I can look at it.

@jwbats
Copy link
Author

jwbats commented Sep 28, 2016

At first I was building for Any CPU, which creates a debug/release folder.
But then I switched to x64, and everything ends up in the bin folder. The
argon2 dll was in the same folder as the rest of my binaries. So that
wasn't the problem.

I have now tried to use this nuget package in a console application just
like you. It works right out of the box, when using the Any CPU build
setting. Later on I will have a few more tries with a WebAPI project. I
have run into the same issues as you have.

Did you know there is a setting called "Use the 64 bit version of IIS
Express" in VS 2015? You can find it under "Projects and Solutions" -> "Web
Projects".

I would really like to just run my application in 64 bit. It's going to be
a program that targets a huge audience and I'm contemplating loading a huge
amount of data in memory to serve requests quickly. Don't wanna run out of
memory at 4GB.

Soon, I will have another shot at this to see if I can get argon2 working
in my WebAPI project. I'll let you know how it works out.

By the way... this is the hash I got from my console app, using the default
settings for "mypassword".

$argon2i$v=19$m=8192,t=3,p=1$qXWS7HplpNzq1QTZKhIoFw$Zbu0Z1SAWvCDwYJ0m36o4iFfPqu9jVyT/DHRy6pzCU0

Is this whole string the hash? I wasn't expecting it to contain readable
information. Is it not a security risk to let people know upfront which
hashing algo was used to create a hash?

On Wed, Sep 28, 2016 at 6:26 AM, Kevin Spinar notifications@github.com
wrote:

@jwbats https://github.com/jwbats, you said that libargon2.dll is in
the Debug folder but then you said your build is in the bin folder--is the
libargon2.dll not with the rest of the dlls from your build? If so, that is
probably the problem. They should all be in the same folder. I think that
might happen if your solution platform doesn't match your project platforms.

When you open up the configuration manager, make sure that the "Active
solution platform" dropdown in the top right is set to x64 and that all the
projects in the grid below have the Platform also set to x64. If there's a
mismatch, then that could be the problem.

You may also try adding a new platform for x86 in the configuration
manager. In the solution platform dropdown, you should be able to select
and select x86 in the new window that pops up. Again, make sure that all
the projects are also set to x86.

Honestly, I did most of my testing with console applications. I did some
testing today with creating a Web API application. I ran into issues when
setting the configuration to x64--the Visual Studio debugger doesn't appear
to support x64, so then I had to set my project to use local IIS, and then
I had issues with IIS not having permission to access the libargon2.dll,
and it was just a mess. Using x86 instead was a lot smoother, so I would
recommend trying that.

I hope that helps. Yeah, you can send me your code if you're still having
problems and I can look at it.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#2 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AL9zgOKFSlFK52IfiLt_z7q9tgvoqzsXks5quexzgaJpZM4JuJE4
.

@jwbats
Copy link
Author

jwbats commented Sep 28, 2016

Solved the problem!

I am running a WebAPI project that references a Core project, which is a DLL.

The Core had the package installed and correctly received libargon2.dll. WebAPI did not have it installed and as such was unable to locate libargon2.dll in its own bin folder.

It did copy Liphsoft.Crypto.Argon2.dll in there, so I mistakenly thought it had everything it needed.

Speaking of bin folders (I mentioned this in my previous posts)... I just found out WebAPI projects need to have their output path set to 'bin' and not 'bin/Debug' or 'bin/x64/Debug'. And if you dare change it, there's gonna be trouble.

@jwbats
Copy link
Author

jwbats commented Sep 28, 2016

I am reading the argon2 documentation and now have questions:

  1. Argon2 apparently supports salt lengths as an input parameter. Why does the liphsoft wrapper not? Would've been convenient if I didn't have to generate my own salts.
  2. The documentation recommends tweaking until you get 1ms hash times on recent hardware. My hardware is recent and I am getting 25ms hash times with the default settings: time=3, mem=8192, parallelism=1. Why have these default settings been chosen? The docs recommend time=2, mem=512, parallelism=2.

@alipha
Copy link
Owner

alipha commented Sep 29, 2016

If you use PasswordHasher.Hash(string password), it will generate a secure, random 16-byte salt for you and encodes the salt into the hash output. So just use that. I'm not sure under what condition you would want a salt of a different length or generate your own salt, but if so, you'd do:

var hasher = new PasswordHasher();
var salt = PasswordHasher.GenerateSalt(32);
var hash = hasher.Hash(Encoding.UTF8.GetBytes("mypassword"), salt);

But really, just use hasher.Hash("mypassword").


That's not the official Argon2 documentation--that's the documentation for someone's port to Python. Argon2 was originally written in C and is here: https://github.com/P-H-C/phc-winner-argon2

I'm not sure why the author of that python port would recommend a target time under 1ms. That seems extremely low. You want the hash time to be as large as possible for your situation. Unless you're expecting a really high traffic website that needs to serve hundreds of logins a second (very little traffic on a site is actually someone logging in), then 1ms is too low and not nearly as secure as it probably could be. 25ms is probably appropriate for a site wanting to serve a couple dozen logins a second.

If instead of running Argon2 on a server, you were instead running Argon2 locally where you only need to hash one password at a time (perhaps as a key-derivation function to do password-based encryption), then really, I would crank up the time and memory parameters (and perhaps set parallelism to 4) so that it takes about a second to perform the hash. A single user won't care waiting a second after entering their password. It's only in a server environment where the server is having to perform several hashes at the same time because multiple people are logging in at the same time that you need lower parameters.


And I never answered your question about whether it's a security risk for all the parameters and salt to be encoded into the Argon2 hash. In cryptography, all these algorithms and systems are written with the principle that we need to assume the attacker knows everything except for the key (or password). If your server was hacked, then you have to assume that the hacker got everything--your database, configuration files, and application code. In which case, if you're not storing the Argon2 parameters in your database, they still have to be somewhere, either in config files or the application code and so the hacker will eventually find them.

Okay, yes, if the hacker only was only able to get the database and the parameters weren't in the database, then they would have more trouble cracking the passwords. But, let's say the hacker already has a username and password of his own in the database because he made an account with your site. Now he can figure out what the parameters are by trying different parameters with his own password until he reproduces his hash. Now he can start brute forcing other people's passwords since he knows what the parameters are. So this would be another situation where hiding them wouldn't really help.

Plus having the parameters built into the Argon2 hash output makes it a lot easier to change the parameters later. For instance, you might want to increase the parameters if you upgrade to new server hardware which can hash the passwords faster. Or, you might want decrease the parameters if you find that the amount of traffic you're seeing has grown a lot and your servers can't handle the traffic anymore. In either case, you can't update the hash parameters of the existing hashes all at once because you need the corresponding passwords, so instead you'd have to generate new hashes as people gradually log into the server. And so that means keeping track of which users are using which Argon2 parameters, and the whole thing is a lot easier if the parameters are right there with the hash.

But I will concede that a little obscurity can improve your security as long as you're not depending upon obscurity. However, there's a much easier and more effective way to add some obscurity and separate a piece of knowledge away from the database of passwords: add some global "pepper". "Password pepper" is an actual term that you can google if you want to read more about it, but the idea is that you have some application-wide value that you append to all your passwords:

string passwordPepper = ConfigurationManager.AppSettings["PasswordPepper"];
var hasher = new PasswordHasher();
var hash = hasher.Hash("mypassword" + passwordPepper);
// store hash in the database
// ...
if(hasher.Verify("mypassword" + passwordPepper))
// ...

You would want this password pepper to be at least 16 randomly-generated bytes and you could store it in your configuration file or even hard-code it into your source code. This accomplishes the same thing (and does it more effectively) as keeping the Argon2 parameters secret: the attacker needs the pepper or the password database is useless.

@cosmin-ionita
Copy link

cosmin-ionita commented Sep 29, 2016

For anyone that is facing the initial problem of this issue, here is my workaround:

  1. Install the Argon2 via NuGet
  2. Implement the logic that you want using hashing
  3. Clean & Rebuild the solution
  4. In the /bin folder of the project that uses the Liphsoft.Crypto.Argon2.dll you will find the problematic libargon.dll
  5. If you try to run the logic that does the hashing you will get an exception, telling you that the libargon.dll could not be found, which is actually the problem.

I've found out that WebAPI doesn't know by default how to load unmanaged dll files, you need to specify in the PATH the directory where unmanaged dll's are located.

Also, you need to give the IIS the right permissions to access that folder. In order to do that, make sure that you have checked the Internet Information Services feature in the Windows Features window. Then, go to Administative Tools -> Internet Information Services Manager -> Application Pools -> << Your Application Pool >>.

By default, there is one Application Pool named DefaultAppPool. Right click on it, Advanced Settings -> Identiy -> Edit.

Here is selected the built in account, named ApplicationPoolIdentity. You must select CustomAccount -> enter your account credentials (the account of the current machine that you are on).

There is one step left: go to Environment Variables -> Add to the PATH the path of the /bin directory where libargon.dll (the unmanaged dll) is located.

Now it should work flawlessly.

My Configuration:

-> Visual Studio 2015 V14.0.25123.00 Update 2
-> Windows 10 Pro 64-bit, Build 14393
-> IIS Version 10.0.14393.0

Another workaround: if you don't want to spend time configuring the IIS (although there are simple configurations) you can copy your unmanaged dll into C:\Windows\SysWOW64 without making any changes to the PATH or to the IIS. This should work too.

Thank you respectfully,

Cosmin Ionita

@jwbats
Copy link
Author

jwbats commented Sep 29, 2016

@alipha Thanks for the clarifying feedback. I learned a lot from this. I wasn't aware that the PasswordHasher was capable of generating a salt for me.

However, I don't see how a pepper will obscure the resulting hash. You are using the pepper like I would use a manual salt ("mypassword" + pepper). The result of this is just a string that is hashed and yields a parametered argon2 hash string.

I am currently using UrlTokenEncode to encode my randomly generated bytes and whatnot. It's handy for sending account verification strings along in a URL.

Not sure if it would add significant time for a hacker to get to my passwords if I use this encoding on my argon2 hashes. And like you said, it's handy having the information there. A hacker would still have to invest significant amounts of time to crack'em one by one.

@alipha
Copy link
Owner

alipha commented Sep 29, 2016

@jwbats With a salt, the salt is stored with the password hash so that you can have a unique salt per user. With a pepper, it's one random blob that's the same for all users that is hidden somewhere away from the database that hopefully an attacker won't be able to find.

@jwbats
Copy link
Author

jwbats commented Sep 29, 2016

Now it all makes sense. I looked up some more info regarding the pepper. The approved answer in this thread makes it pretty clear. Thanks again!

@alipha alipha closed this as completed Sep 30, 2016
@johnstaveley
Copy link

I get "System.DllNotFoundException: Unable to load DLL 'libargon2.dll': The specified module could not be found" when running tests using this on my TeamCIty build server.

Is there any other way of solving this other than sticking the dll in the path? I thought .Net checked the local directory first (which is where libargon2.dll can be found). There must be a way of allowing a solution to see an unmanaged dll. I have in the same directory as the build and tests which are being run but apparently TeamCity still can't see them. Sticking libargon2.dll into the path seems a rather nasty hack. I've read somewhere that the dll is copied to a temporary folder location first which is why I get the Unable to load DLL error above, putting it in the path would fix that but it is not the underlying problem as libargon2.dll can be found everywhere the NuGet package (I'm using 1.0.5) dlls are being used.

@jwbats
Copy link
Author

jwbats commented Dec 15, 2016 via email

@johnstaveley
Copy link

It is installed in the test project which runs fine locally but fails on the CI server. Despite the fact the libargon2.dll being present in the same directory as the test code which is being executed

@jwbats
Copy link
Author

jwbats commented Dec 15, 2016 via email

@johnstaveley
Copy link

johnstaveley commented Dec 15, 2016 via email

@kunalkakkad
Copy link

kunalkakkad commented Jun 15, 2017

@cosmin-ionita I am facing the issue over 3rd party hosting server where I am having shared hosting. So how can I handle the same?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants