Can I uniquely identify a device in Windows 10/Windows 8/WinRT - windows-8

Is there any mechanism to identify a device uniquely (even if it is anonymous)?
To be clear, by "device" I mean the computer/slate/pc.
Windows 8.x
http://codepaste.net/ybt893
string HardwareId()
{
var token = Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null);
var hardwareId = token.Id;
var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(hardwareId);
var bytes = new byte[hardwareId.Length];
dataReader.ReadBytes(bytes);
return BitConverter.ToString(bytes);
}
Windows 10
You must add the Mobile and/or Desktop extension SDK.
string HardwareId()
{
var token = HardwareIdentification.GetPackageSpecificToken(null);
var hardwareId = token.Id;
var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(hardwareId);
var bytes = new byte[hardwareId.Length];
dataReader.ReadBytes(bytes);
return BitConverter.ToString(bytes);
}

Such an ability has just been added in Windows 8 RTM:
Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null)

There doesn't seem to be a convenient way for Metro Style apps in Windows 8 to obtain a system-maintained unique identifier, like Windows Phone 7 provided with its Microsoft.Phone.Info.DeviceExtendedProperties.GetValue( "DeviceUniqueId" )
http://social.msdn.microsoft.com/Forums/en-HK/winappswithcsharp/thread/62ac2a48-be60-465c-b3b7-bbb736a67a60
http://social.msdn.microsoft.com/Forums/en-NZ/winappswithcsharp/thread/2ca0d5de-9db5-4349-839c-e01ff614ec6e
The best solution I've found so far is to simply generate a new guid in application local storage and use that identifier to identify the computer for the current and future launches of your app.
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
Object value = localSettings.Values["uniqueDeviceId"];
if (!value)
{
value = Guid.NewGuid();
localSettings.Values["uniqueDeviceId"] = value;
}
Keep in mind that the user could delete the local storage and cause your app to forget and regenerate that value (or potentially even modify/spoof the value), so don't depend on it for any critical security purposes. Since I'm only using this technique for rough statistics and usage reporting, this is fine for my needs.

Could this be used as a consistent ID for the logged in user?
http://msdn.microsoft.com/en-us/library/windows/apps/windows.security.exchangeactivesyncprovisioning.easclientdeviceinformation.id.aspx
EasClientDeviceInformation.Id | id property
Returns the identifier of the local computer. The Id property represents the DeviceId using the GUID truncated from the first 16 bytes of the SHA256 hash of MachineID, User SID, and App ID where the MachineID uses the SID of the local users group. Each component of the GUID is returned in network byte order.

Related

Encrypting Password Like Forms Authentication in .net Core

I have an old app that runs a read only membership provider. I am tasked with creating an admin page to help with adding/changing/deleting users from this app. The membership provider uses FormsAuthentication, which I cannot use because my admin app is in .net Core. I'm trying to reverse-engineer the way they encrypt using FormsAuthentication and I have this so far:
They use:
FormsAuthentication.HashPasswordForStoringInConfigFile(password, "sha1").ToLower();
I've reverse-engineered it to:
(string pwd is passed in)
HashAlgorithm hashAlgorithm = new HMASHA1();
var step1 = Encoding.UTF8.GetBytes(pwd);
var step2 = hashAlgorithm.ComputeHash(step1);
var step3 = BinaryToHex(step2);
And step3 comes out to something like this "AD626B9D42073B299ECFC664CCB7A8B01F3AF726", which looks like what the passwords look like in the XML user file for the old app.
I'm just curious if I use this method of hashing (which works in .net core), will the hashed passwords be able to be "validated" by FormsAuthentication?
My tests so far don't seem to be working. Any ideas? Am I doing it wrong?
EDIT: it is not HMASHA1, it's SHA1Cng - which I can't use because it is in System.Core in the .net framework 4.something... what can I use to do this in .net core?
I figured it out, this works:
using System.Security.Cryptography;
var sha1 = SHA1.Create();
var step1 = Encoding.UTF8.GetBytes(pwd);
var step2 = sha1.ComputeHash(step1);
var step3 = BinaryToHex(step2);
BinaryToHex and it's associated functions are copied from System.Web.Security.Cryptography.CryptoUtil
Would still like to be able to do this in reverse and decrypt passwords.
Slightly different take, legacy hashed passwords in database
string incoming = inCrypt(inputPassword);
incoming=Regex.Replace(incoming, #"[^0-9a-zA-Z]", "");
public string inCrypt(string pwd)
{
var sha1 = SHA1.Create();
var step1 = System.Text.Encoding.UTF8.GetBytes(pwd);
var step2 = sha1.ComputeHash(step1);
var step3 = BitConverter.ToString(step2);
return step3.ToString();
}
it worked, and the hashed passwords can be compared as strings.

AspNet Identity UserManager Find with Select (optimal sql query)

I have wcf fulRest service with AspNet Identity. My android app use this web service to communicate with database - I use ssl to make connection secure (my app is a mini game so it doesn't contain so important data, I belive that ssl is enough protection in this case).
I have function LoginUser(string userName, string unHashedPassword), if user exsists it returns user's id. In all other functions this id is used if action need information of curUser - for example I have function addComment(string userId, string msg) (this kind of methods still use ssl to protection of unwanted handle userId).
In LoginUser I get id (and a little more information like e-mail, gameLogin) by use:
using (var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(_context)))
{
ApplicationUser user = userManager.Find(userName, password);
if (user != null)
{
result = new LogInBaseData()
{
Id = user.Id,
Email = user.Email,
Login = user.ApplicationLogin
};
}
}
But function Find generate huge query with select many unneeded data for me. Is any way to optimalizace it? I prefer do it by context.User.Where().Select() but I can't hash user's password.

Act on Behalf of different user / XrmServiceContext.CallerID

I have created a XrmServiceContext using svcutil.exe for my CRM 2013 database, this is working great and I can retrieve data from CRM in my MVC4 application.
My website is running SSO using ADFS2 and I can retrieve the accessing users identity using:
Microsoft.IdentityModel.Claims.IClaimsIdentity ci = Thread.CurrentPrincipal.Identity as Microsoft.IdentityModel.Claims.IClaimsIdentity;
var accountNameClaim = ci.Claims.Where(x => x.ClaimType.ToLower().EndsWith("windowsaccountname")).FirstOrDefault();
this gives me something along the lines of
string accountNameClaim = "firstname.lastname#domain.com"
Using this I can retrieve the user form CRM 2013 XrmServiceContext
var user = _serviceContext.SystemUserSet
.Where( x=> x.DomainName == accountNameClaim)
.Select(s => new UserInformationProxy()
{
Id = s.Id, // this is probably needed for impersonation
FullName = s.FullName,
DomainName = s.DomainName
})
.FirstOrDefault();
Now I'm wondering how I act as / impersonate this user for all my subsequent queries to CRM using my XRMServiceContext.
This page http://msdn.microsoft.com/en-us/library/gg309629.aspx has a guide which suggests I need to set a variable called CallerID in OrganizationServiceContext which I'm guessing is contained somewhere inside my XRMServiceContext.. But I cannot find it.
The CallerId property is not on the OrganizationServiceContext but on the OrganizationServiceProxy that is used by the context:
When you are constructing the context, you are passing in an organization service intance. Prior to that, you need to set the CallerId:
organizationService.CallerId = user.Id;
var _serviceContext = new OrganizationServiceContext(organizationService);
Please note that the CallerId is only available on the OrganizationServiceProxy type, not on the interface IOrganiaztionService. I can't see how you obtain the organization service, but make sure it's an OrganizationServiceProxy.

How can I generate date-dependent passwords?

I'm looking for a simple way to generate passwords that will only work once for a limited amount of time, e.g. 1 day, 1 week, 1 month. This has to be implemented in an application that has no connectivity so a server isn't possible. The use case is something like:
1. Generate password for a specific date and length of time.
2. Send to user (email, phone, etc).
3. User enters in application.
4. Application is enabled for a specific time.
5. Password cannot be reused, even on another PC.
I'm assuming the only way to do this is to generate passwords that only work between a specific set of dates. Can anyone recommend an algorithm that can do this? It doesn't have to be incredibly secure, and I know you can crack this by resetting the time on the PC!
Thanks.
I know I'm late but I'll provide my advice anyway in case someone else who needs it found their way here.
To prevent it being used on another PC, you could probably use the MAC address or hardware address. However, this is subject to the network hardware being still available when checking the password. Please make sure you use the hardware address of the machine where the password will be checked.
private string GetBase64Mac()
{
System.Net.NetworkInformation.NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
if (interfaces.Length == 0)
{
System.Net.NetworkInformation.PhysicalAddress add = interfaces[0].GetPhysicalAddress();
if (add != null)
return System.Convert.ToBase64String(add.GetAddressBytes());
}
return "";
}
To limit it by some expiry date simply use the text string of the expiry date.
private string GetExpiryDate(DateTime expiryDate)
{
return expiryDate.ToString("yyyyMMdd");
}
Simply use a hash function to hash the combine expiry date, hardware address and a secret key. Prefix or suffix the hash output with the expiry date.
private void GeneratePassword(string prefix)
{
string secretKey = "MySecretKey";
System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create();
byte[] preHash = System.Text.Encoding.UTF32.GetBytes(prefix + secretKey + GetBase64Mac());
byte[] hash = sha.ComputeHash(preHash);
string password = prefix + System.Convert.ToBase64String(hash);
return password;
}
In the case above, i prefix the hash with the expiry date. So, when we check the password, we simply extract the expiry date from the password, use the same function to generate the same password. If the generated password match the provided password, then you have green light.
private void TestPassword()
{
int duration = 15; // in days
string prefix = GetExpiryDate(DateTime.Today.AddDays(duration));
string generated = GeneratePassword(prefix);
// Positive test
string testPrefix = generated.Substring(0, 8);
string testPassword = GeneratePassword(testPrefix);
if (generated != TestPassword)
return false;
// Negative test
generated[2] = '2';
generated[12] = 'b';
testPrefix = generated.Substring(0, 8);
testPassword = GeneratePassword(testPrefix);
if (generated != TestPassword)
return true;
return false;
}
Sample output password:
20110318k3X3GEDvP0LkBN6zCrkijIE+sNc=
If you can't get the hardware address, then simply use the customer's name. It won't prevent the password from being used in multiple machines, but it will ensure that the same person is using it.
Your application should have a attribute like validity for the password something like this
username password_hash validity_from Validity_end
xyz a73839$56 11-Nov-2010 12-Nov-2010
and then in your application you can validate that your password has expired or not
Generate passwords by any method you'd like (a word list, random letters, etc). Put them into some data structure, like an associative array, where you can associate a date with each password. Then you consult this data structure in the program that hands out passwords to give one out with the proper expiration date. The client program has the same list of passwords and dates, so when it gets a password, it just looks up the associated expiration date there.

Selenium with BrowserMob.com

I am working with Selenium in order to create load balancing tests on a web server. The website has a username/password and in order to work with this I have a csv file filled with username password combinations.
The issue is I am using the random function in Javascript to select a row from the csv file and populate the login functionality or registration details.
var csv = browserMob.getCSV("pickStickEmails.csv");
var row = csv.random();
var Email = row.get("email");
var Password = row.get("password");
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxEmail", Email);
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxEmailConfirm", Email);
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxPassword", Password);
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxPasswordConfirm", Password);
This obviously brings up issues when registering if the same record is selected twice during a scheduled run. Obviously with the login situation if a record isn't selected when registering and is then selected on a test that requires an existing account the test fails due to it not existing.
My question is, is it possible to somehow get browserMob to iterate through the records one at a time? Obviously when browserMob begins a load test it ramps up to lets say 10 users using the website at one time each running the script I assume?
I did write the test using Selenium-RC in C# with NUnit and read the csv file into a List and then iterated through the list. Obviously this runs each user after another and doesn't simulate multiple users being on the site at one time.
Any advice on this would be greatly appreciated.
Thanks,
Jon
To enforce unique parameterization you need to call browserMob.getUserNum() as that will get the user number for that node that is processing your test. You can see this in their help. I have updated your code to how I think it should look. Should means I have not tested it :)
var csv = browserMob.getCSV("pickStickEmails.csv");
var row = browserMob.getUserNum();
var Email = row.get("email");
var Password = row.get("password");
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxEmail", Email);
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxEmailConfirm", Email);
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxPassword", Password);
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxPasswordConfirm", Password);
I think this could possibly be a way to get a unique record for each user during a load test:
var csv = browserMob.getCSV("pickStickEmails.csv");
var rowNumbers = new Array();
for(i = 0; i <= csv.size(); i++)
{
rowNumbers.push(i);
}
var uniqueRowNumber = rowNumbers[browserMob.getUserNum()];
var row = csv.get(uniqueRowNumber);
var Email = row.get("email");
var Password = row.get("password");
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxEmail", Email);
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxEmailConfirm", Email);
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxPassword", Password);
selenium.type("ctl00_StandardMainBodyPlaceHolder_ctl00_TextBoxPasswordConfirm", Password);
It basically creates an array of numbers which act as row numbers for the csv file. Then it just uses the get() function on the CsvTable instead of random using the unique number selected from your suggestion.
Thank's for the guidance!