Attempting to use SHA1 hashing to send password to Google

986 views Asked by At

I am currently working on a program with Google's Directory API to reset the password of someone in my domain. I have it all working, but I would like to send an encrypted password to Google instead of plaintext. Since the API seems limited in what I can use to encrypt, I'm trying to use SHA-1 to do so. The problem is, when I encrypt it in SHA-1, Google doesn't accept it.

Here is my original code of what I was sending to Google:

//create a template of the user to update
var body = new Google.Apis.Admin.Directory.directory_v1.Data.User();

//Encrypt the password using SHA1        
byte[] bytes = System.Text.Encoding.Unicode.GetBytes(model.NewPassword);
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] password = sha.ComputeHash(bytes);

//Put the password and hash function into the request body
body.HashFunction = "SHA-1";
body.Password = password.ToString();

//send the request
var request = users.Update(body, email);
request.execute();

When I run this, it throws an error saying the password is invalid.

when I change it so that it is sending strictly hex, like so

//create a template of the user to update
var body = new Google.Apis.Admin.Directory.directory_v1.Data.User();

//Encrypt the password using SHA1
byte[] bytes = System.Text.Encoding.Unicode.GetBytes(model.NewPassword);
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] password = sha.ComputeHash(bytes);

//Convert the hashcode to Hex
System.Text.StringBuilder builder = new System.Text.StringBuilder();
for (int i = 0; i < password.Length; i++)
{
    builder.Append(password[i].ToString("x2"));
}


//Put the password and hash function into the request
body.HashFunction = "SHA-1";
body.Password = builder.ToString();

//send the request
var request = users.Update(body, email);
request.execute();

Then Google accepts what I've given it, but going into the account, I can't access it, because the password was changed to something completely different.

Am I just encrypting the password incorrectly, or is there something I'm missing?

1

There are 1 answers

0
Jon Skeet On BEST ANSWER

(Disclaimer: I work for Google, but I haven't looked at this API before.)

Well, the problem when you call password.ToString() is that it's not providing the hex representation - so that's why the first piece of code fails. It looks like it's basically expecting it to be hex. The documentation states:

We recommend sending the password property value as a base 16 bit encoded hash value. If a hashFunction is specified, the password must be a valid hash key.

Now, I suspect the problem with the second piece of code is the way you're converting the original text password to bytes. You're using:

Encoding.Unicode.GetBytes(model.NewPassword)

That's using little-endian UTF-16. While the documentation doesn't state the expected encoding, using UTF-8 would be more common. So I would suggest using

Encoding.UTF8.GetBytes(model.NewPassword)

instead... and then hashing the result and hex-encoding that hash as before.

That's only an educated guess, but it's worth a try.