zetetic has a pretty sweet encryption library that includes support for bcrypt2. It looks like it should be straightforward enough to incorporate into an ASP.NET Membership Provider (in fact, instructions for the default provider can be found here). I am using an NHibernate Membership Provider (found here) which seems to hard code the SHA1 hash format in it's EncodePassword function. My question is, how should this be adapted to work with BCrypt2 (specifically Zetetic's wrapper). This is something I greatly fear getting wrong, and I'm reluctant to take a stab at it myself lest it should "work" but have some hidden flaw that I am not qualified to find.
private string EncodePassword(string password)
{
string encodedPassword = password;
switch (PasswordFormat)
{
case MembershipPasswordFormat.Clear:
break;
case MembershipPasswordFormat.Encrypted:
encodedPassword =
Convert.ToBase64String(EncryptPassword(Encoding.Unicode.GetBytes(password)));
break;
case MembershipPasswordFormat.Hashed:
HMACSHA1 hash = new HMACSHA1();
hash.Key = HexToByte(_machineKey.ValidationKey);
encodedPassword =
Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));
break;
default:
throw new ProviderException("Unsupported password format.");
}
return encodedPassword;
}
Are you modifying the NHibernate-based membership provider, or stuck using it out of the box? If the latter, it doesn't look like there's any extensibility.
The ASP.NET SqlMembershipProvider works by accepting the name of a hash algorithm, conjures an instance via HashAlgorithm.Create(name) and then behaves a little differently if the algorithm type turns out to be a KeyedHashAlgorithm or regular (non-keyed) HashAlgorithm. The Zetetic.Security package is just providing a little bit of glue to make BCrypt and PBKDF2 compatible with that model.
The sample code from NHMembershipProvider can't take advantage of that because it's very directly relying on HMACSHA1. I'd note that HMACSHA1 is not a secure algorithm for this purpose, nor is using a static salt for all users acceptable (it's scarcely better than no salt). The app ValidationKey and HMACSHA1 are meant for message integrity only.
Here's a sample:
public class HashDemo
{
private static readonly RNGCryptoServiceProvider s_rng = new RNGCryptoServiceProvider();
public string HashPassword(string pwd, string hashName)
{
var alg = HashAlgorithm.Create(hashName);
if (alg == null)
throw new ArgumentException("Invalid hash name", "hashName");
byte[] tohash = System.Text.Encoding.UTF8.GetBytes(pwd);
var ka = alg as KeyedHashAlgorithm;
if (ka != null)
{
if (ka.Key == null || ka.Key.Length == 0)
{
byte[] key = new byte[20];
s_rng.GetBytes(key);
ka.Key = key;
}
else
{
s_rng.GetBytes(ka.Key);
}
// TODO: return base64(ka.Key || alg.ComputeHash(tohash))
}
else
{
var salt = new byte[20];
s_rng.GetBytes(salt);
using (var ms = new System.IO.MemoryStream(salt))
{
ms.Write(tohash, 0, tohash.Length);
tohash = ms.ToArray();
}
// TODO: return base64(salt || alg.ComputeHash(tohash))
}
}
}
Related
I'm in a situation where I have a dataset that consists of the classical UserID, ItemID and preference values, however they are all strings.
I have managed to read the UserID and ItemID strings by Overriding the readItemIDFromString() and readUserIDFromString() methods in the FileDataModel class (which is a part of the Mahout library) however, there doesnt seem to be any support for the conversion of preference values if I am not mistaken.
If anyone has some input to what an approach to this problem could be I would greatly appreciate it.
To illustrate what I mean, here is an example of my UserID string "Conversion":
#Override
protected long readUserIDFromString(String value) {
if (memIdMigtr == null) {
memIdMigtr = new ItemMemIDMigrator();
}
long retValue = memIdMigtr.toLongID(value);
if (null == memIdMigtr.toStringID(retValue)) {
try {
memIdMigtr.singleInit(value);
} catch (TasteException e) {
e.printStackTrace();
}
}
return retValue;
}
String getUserIDAsString(long userId) {
return memIdMigtr.toStringID(userId);
}
And the implementation of the AbstractIDMigrator:
public class ItemMemIDMigrator extends AbstractIDMigrator {
private FastByIDMap<String> longToString;
public ItemMemIDMigrator() {
this.longToString = new FastByIDMap<String>(10000);
}
public void storeMapping(long longID, String stringID) {
longToString.put(longID, stringID);
}
public void singleInit(String stringID) throws TasteException {
storeMapping(toLongID(stringID), stringID);
}
public String toStringID(long longID) {
return longToString.get(longID);
}
}
Mahout is deprecating the old recommenders based on Hadoop. We have a much more modern offering based on a new algorithm called Correlated Cross-Occurrence (CCO). Its is built using Spark for 10x greater speed and gives real-time query results when combined with a query server.
This method ingests strings for user-id and item-id and produces results with the same ids so you don't need to manage those anymore. You really should have look at the new system, not sure how long the old one will be supported.
Mahout docs here: http://mahout.apache.org/users/algorithms/recommender-overview.html and here: http://mahout.apache.org/users/recommender/intro-cooccurrence-spark.html
The entire system described, with SDK, input storage, training of model and real-time queries is part of the Apache PredictionIO project and docs for the PIO and "Universal Recommender" and here: http://predictionio.incubator.apache.org/ and here: http://actionml.com/docs/ur
I wrote the following code to find out if the user logging has an account at active directory so i may allow him to proceed and it's working fine:
public bool AuthenticateUser(string domain, string username, string password, string LdapPath)
{
string domainAndUsername = domain + #"\" + username;
DirectoryEntry entry = new DirectoryEntry(LdapPath, domainAndUsername, password);
try
{
// Bind to the native AdsObject to force authentication.
Object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if (null == result)
{
return false;
}
and it works great, the only problem is that i need to make the same thing using xamarin forms , how may I?
DirectorySearcher is a class that you would use from a server API/code.
I suggest you to create a Web API that would do the same job and that will be called by your Xamarin application.
I spent hours on this problem without finding the solution. Other questions come close but none of the suggested solutions work for me.
I'm running on
- Grails 2.1.1 installed with
- Groovy 2.0.8 and
- Oracle Java v 1.6.0_45 (also tried with 1.7 already)
I added the Spring Security Core Plugin v 2.0-RC2.
I'm a Grails beginner and all I want to do is create a "Runner" with a password using my own password validator.
This is my Runner.groovy domain class (did not change very much from the default Spring Security User template apart from the renaming):
package de.muden.runnerbase
class Runner {
transient springSecurityService
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
Date dateCreated
Profile profile
public static final int MIN_PASS_LENGTH = 6
public static final int MAX_PASS_LENGTH = 20
static transients = ['springSecurityService']
static constraints = {
username(size:3..20,unique:true)
password(nullable:false, blank:false, minSize:6, validator: { passwd, runner ->
return (passwd != runner.username && validatePasswordInplace(passwd))
})
dateCreated()
profile(nullable:true)
}
static mapping = {
profile lazy:false
runs sort:'dateCreated'
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
String toString() {
return "Runner '$username'"
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
protected static boolean validatePasswordInplace(String passToValidate) {
println "VALIDATING PASS $passToValidate"
return passToValidate ==~ /([A-Za-z0-9äöüÄÖÜß.!\?_-]){$MIN_PASS_LENGTH,$MAX_PASS_LENGTH}/
}
static hasMany = [runs: Run, shoes: Shoe]
}
So the validator allows passwords between 6 and 20 characters long, upper and lower case letters, numbers and a few special characters.
Simple unit tests just testing this method work as expected.
Now a simple integration test:
void testValidRunner() {
Runner r = new Runner(username:'dummy',password:'foobar')
assertTrue r.validate() // OK
assertFalse r.hasErrors() // OK
assertNotNull r.save(flush:true,failOnError:true) // OK
Runner foundRunner = Runner.findByUsername("dummy")
assertNotNull foundRunner // fails, foundRunner = null
assertEquals('dummy',foundRunner.username)
}
And the console (with -echoOut) says:
VALIDATING PASS foobar
VALIDATING PASS $2a$10$Q5RYaDrCFFxdXEqYqV4J2OJWHzgOJZJ3wljqVK1jNP4Sqm6ZUOPam
It is obvious that the second validation fails. But why is grails validating the encoded password again? And why doesn't r.validate() complain? Where exactly does that second validation happen?
I have the feeling that I'm doing really basic user password encryption wrong here...
First I thought it had to do with the Spring Security fields "accountExpired" etc. being added and not in the constraints block. But when I remove the custom validator everything works fine.
Any help is appreciated :-)
Thanks,
Matt
Below is what I think is going on ...
The second validation happens when you call r.save
The beforeInsert method is calling the encodePassword method, which is encoding the PW to the long string $2a$10$Q5RYaDrCFFxdXEqYqV4J2OJWHzgOJZJ3wljqVK1jNP4Sqm6ZUOPam
That is the string that will be validated and saved in the DB not 'foobar'
I believe that your regex does not allow the dollar sign, which is part of the encoded string resulting in the failure.
I do not think that using constraints will work for what you want to do. You need to validate before it is encoded, so you probably need to add separate validation code (in the domain class or elsewhere) and validate the PW before assigning to the PW field and saving the object.
I'm trying out Dapper with Oracle and I was trying to run a multi-resultset query but Oracle requires a dbtype of refcursor.
StringBuilder query = new StringBuilder("BEGIN ");
query.Append("OPEN :rs1 FOR SELECT * FROM Table1 where key=:KEY; ");
query.Append("OPEN :rs2 FOR SELECT * FROM Table2 where key=:KEY; ");
query.Append("END;");
Is there a way to pass an OracleParameter (maybe as DbParameter?) to Dapper? When I tried, it threw an error.
What is the advantage of using the DynamicParameter vs. using a DbParameter (assuming types are known etc.)?
A new interface was added in the most recent build that allows more control over the parameter - it was added to support TVPs in SQL server, but should work in this scenario. However, I'm also fairly content to add special casing for any types that look like dbparameter - and add them directly, which would allow you to add an oracleparameter directly.
DynamicParameters is about how many parameters to add, so it is a bit orthogonal to the value vs DbParameter discussion. At the moment, the code generally prefers to take control of adding parameters itself, so the caller just knows "an int named id with value 7" - not any ado.net details. But it could do.
Edit: if you really want to work with lists-of-parameters (i.e. List<DbParameter> etc), then you can do that with something like:
public class DbParams : Dapper.SqlMapper.IDynamicParameters,
IEnumerable<IDbDataParameter>
{
private readonly List<IDbDataParameter> parameters =
new List<IDbDataParameter>();
public IEnumerator<IDbDataParameter> GetEnumerator() {
return parameters.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public void Add(IDbDataParameter value)
{
parameters.Add(value);
}
void Dapper.SqlMapper.IDynamicParameters.AddParameters(IDbCommand command,
Dapper.SqlMapper.Identity identity)
{
foreach (IDbDataParameter parameter in parameters)
command.Parameters.Add(parameter);
}
}
with usage like:
public void TestCustomParameters()
{
var args = new DbParams {
new SqlParameter("foo", 123),
new SqlParameter("bar", "abc")
};
var result = connection.Query("select Foo=#foo, Bar=#bar", args).Single();
int foo = result.Foo;
string bar = result.Bar;
foo.IsEqualTo(123);
bar.IsEqualTo("abc");
}
which passes the test.
However, I must stress that I would prefer not to encumber the calling code with db-parameter knowledge unless it really really needs to know; I would by-far prefer:
var args = new {
foo = 123, bar = "abc"
};
which does exactly the same thing, but without dropping to ADO.NET; this can be especially important if you are using a "decorated" ADO.NET connection (for example, mini-profiler) - in which case the layer you get is not an OracleCommand / OracleConnection etc - it is abstracted. This means that forcibly adding an OracleParameter may not always work - but adding a parameter with name "foo" and value 123 - that is pretty reliable.
Currently I'm developing an OAuth2 authorization server using DotNetOpenAuth CTP version. My authorization server is in asp.net MVC3, and it's based on the sample provided by the library. Everything works fine until the app reaches the point where the user authorizes the consumer client.
There's an action inside my OAuth controller which takes care of the authorization process, and is very similar to the equivalent action in the sample:
[Authorize, HttpPost, ValidateAntiForgeryToken]
public ActionResult AuthorizeResponse(bool isApproved)
{
var pendingRequest = this.authorizationServer.ReadAuthorizationRequest();
if (pendingRequest == null)
{
throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
}
IDirectedProtocolMessage response;
if (isApproved)
{
var client = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
client.ClientAuthorizations.Add(
new ClientAuthorization
{
Scope = OAuthUtilities.JoinScopes(pendingRequest.Scope),
User = MvcApplication.LoggedInUser,
CreatedOn = DateTime.UtcNow,
});
MvcApplication.DataContext.SaveChanges();
response = this.authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, User.Identity.Name);
}
else
{
response = this.authorizationServer.PrepareRejectAuthorizationRequest(pendingRequest);
}
return this.authorizationServer.Channel.PrepareResponse(response).AsActionResult();
}
Everytime the program reaches this line:
this.authorizationServer.Channel.PrepareResponse(response).AsActionResult();
The system throws an exception which I have researched with no success. The exception is the following:
Only parameterless constructors and initializers are supported in LINQ to Entities.
The stack trace: http://pastebin.com/TibCax2t
The only thing I've done differently from the sample is that I used entity framework's code first approach, an I think the sample was done using a designer which autogenerated the entities.
Thank you in advance.
If you started from the example, the problem Andrew is talking about stays in DatabaseKeyNonceStore.cs. The exception is raised by one on these two methods:
public CryptoKey GetKey(string bucket, string handle) {
// It is critical that this lookup be case-sensitive, which can only be configured at the database.
var matches = from key in MvcApplication.DataContext.SymmetricCryptoKeys
where key.Bucket == bucket && key.Handle == handle
select new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc());
return matches.FirstOrDefault();
}
public IEnumerable<KeyValuePair<string, CryptoKey>> GetKeys(string bucket) {
return from key in MvcApplication.DataContext.SymmetricCryptoKeys
where key.Bucket == bucket
orderby key.ExpiresUtc descending
select new KeyValuePair<string, CryptoKey>(key.Handle, new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc()));
}
I've resolved moving initializations outside of the query:
public CryptoKey GetKey(string bucket, string handle) {
// It is critical that this lookup be case-sensitive, which can only be configured at the database.
var matches = from key in db.SymmetricCryptoKeys
where key.Bucket == bucket && key.Handle == handle
select key;
var match = matches.FirstOrDefault();
CryptoKey ck = new CryptoKey(match.Secret, match.ExpiresUtc.AsUtc());
return ck;
}
public IEnumerable<KeyValuePair<string, CryptoKey>> GetKeys(string bucket) {
var matches = from key in db.SymmetricCryptoKeys
where key.Bucket == bucket
orderby key.ExpiresUtc descending
select key;
List<KeyValuePair<string, CryptoKey>> en = new List<KeyValuePair<string, CryptoKey>>();
foreach (var key in matches)
en.Add(new KeyValuePair<string, CryptoKey>(key.Handle, new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc())));
return en.AsEnumerable<KeyValuePair<string,CryptoKey>>();
}
I'm not sure that this is the best way, but it works!
It looks like your ICryptoKeyStore implementation may be attempting to store CryptoKey directly, but it's not a class that is compatible with the Entity framework (due to not have a public default constructor). Instead, define your own entity class for storing the data in CryptoKey and your ICryptoKeyStore is responsible to transition between the two data types for persistence and retrieval.