serial key validation in c# - c#

I completed my project in C#.Net.
I Added a serial key in it.
At the time of installation it asks me for the key.
The key format is also given by me, but I don't know how to validate that key.
Please give me some way how to validate that key.
Now my key is validated by visual studio or I don't know who. How is the key's validation done?
But I want to do the validation by my own. Is it possible? And if yes, how?
i added the customer information dialog.
and format is given by using the serial number template.
but for validation it create the problem that visual studio's logic is so simple & it is if the some of digits is / by 7 then key is valid.so i want to use the my logic like use sha1,MD5 so where i have to do coding.
The design of the customer info dialog is not show,if it is shown then i do the coding on validate button.
But now what i have to do?

to write this code you can make an md5 hash according to an algorithm of your own so every user must have a key related to lets say his user name and email address that will unlock if the key is typed correctly. lets say if you have a user name "muster" and an email address "mymail#mail.web" you can combine it in an algorith of your own "simplest one for example is concatination: "mustermymail#mail.web" now encoding md5 hash to it will give a 32 char "9192ec1632022ab6b3706dc053d7b20f" which forms a serial and this serial can't be decrypted unless you know the algorithm that it was encrypted first.
to make an md5 hash value try this:
string text="mustermymail#mail.web";
byte []bytes=System.Text.Encoding.Default.GetBytes(text);
byte []md5Bytes=System.Security.Cryptography.MD5.Create().ComputeHash(bytes);
string md5Text=System.Text.Encoding.Default.GetString(md5Bytes);
Check : http://blogs.msdn.com/b/danielfe/archive/2005/07/10/437293.aspx for starters...

Related

Generate password based on string in C#

I'd like to generate (secure) local admin passwords based on computer names in our organisation. This way I can build a small UI that takes the computername and gives the password.
With PowerShell we will use the same DLL to generate the password and set it on each workstation.
I've already searched, but all the things I find about cryptography in C# is to hash a password, but I need the hash itself to be the password.
The password should also be of a length between 8 and 12 characters to make it easy enough to type it in.
I'm using .NET Core 2.0 (could use .NET Framework too if needed)
You definitely want to be able to change the passwords on your machines, so include some sort of date or counter in the formula.
You ideally also want to include some form of authentication into the tool, whether that be a master password, a complicated thing with smartcards, or something else. That way when your tool gets into the hands of a baddie they don't necessarily get all your data.
If you go the master password route, you need a plan for how to deal with suspecting that got leaked. (Including someone who knew it leaving the organization, since that's a leak.)
A strawman example which includes:
Using a date
Using a master password
Using HMAC to process the machine name, keyed by a key from the master password
An iteration count to PBKDF2 which matches modern computers.
.
private static string GeneratePassword(
string masterPassword,
string machineName,
DateTimeOffset lastChangeDate)
{
// Use the date (ignoring time) of the last password change as a salt.
byte[] salt = BitConverter.GetBytes(lastChangeDate.ToUniversalTime().Date.Ticks);
HashAlgorithmName prf = HashAlgorithmName.SHA256;
using (var pbkdf2 = new Rfc2898DeriveBytes(masterPassword, salt, 123456, prf))
{
byte[] key = pbkdf2.GetBytes(256 / 8);
using (HMAC hmac = new HMACSHA256(key))
{
byte[] value = hmac.ComputeHash(
Encoding.UTF8.GetBytes(machineName.ToUpperInvariant()));
// Or however long.
return Convert.ToBase64String(value).Substring(0, 16);
}
}
}
The Rfc2898DeriveBytes constructor overload which takes a HashAlgorithmName for the PBKDF2-PRF is new in netcoreapp20. If you are trying to be netstandard20 you can drop the last parameter and use the SHA-1-based version with probably little harm (since HMACSHA-1 isn't currently considered broken).
When going to change a password for a machine you'd enter the date of the last generation to get the existing one. Then enter today's date to get the new value, then write down the new date in whatever text file / spreadsheet / database / sticky note remembers these things.
Another alternative is generating random passwords and saving them in an encrypted structured file. Something like EnvelopedCms as the encryption container gives you smartcard for nearly free, and lets you add/remove readers without changing all the machine passwords (adding is easy, removing might warrant changing them all anyways).
Which is to say: Building a stable generator and deploying the usage is easy. It's maintaining it that gets tricky. Maintaining random might be easier, therefore it's possibly better to pay the cost up front.
I don't know if this is such a good idea - the tool only works as long as the passwords on each and every computer stay unchanged.
Anyway, you could hash the computer name and use the result as a password. Most if not all hashes produce larger hashes than 8-12 "easy enough to type in" characters, but you can solve that by:
Base64 encoding the hash (to get letters, numbers and a couple of other characters)
Take the desired number of characters from the result.
To make this a bit safer, let your UI take a password (a single one) and append it to the computer name before computing the hash. This way, when someone steals your tool, they still won't be able to generate valid passwords.
You won't ever be able to change that password, though. If you share it with a coworker, they will know how to reproduce every password, forever.

Identify the recipient(s) KeyId from PGP encrypted data using the BouncyCastle C# library

I have developed a library to perform PGP signing/encryption and decryption/validation of files against one or more recipients. This part works great and works with large files using streams nicely and efficiently.
Part of the PGP Message Exchange Formats specification (RFC 1991) states the following:
...
6.7 User ID Packet
Purpose. A user ID packet identifies a user and is associated with a
public or private key.
Definition. A user ID packet is the concatenation of the following
fields:
(a) packet structure field (2 bytes);
(b) User ID string.
The User ID string may be any string of printable ASCII characters.
However, since the purpose of this packet is to uniquely identify an
individual, the usual practice is for the User ID string to consist of
the user's name followed by an e-mail address for that user, the
latter enclosed in angle brackets.
...
The application I am creating will need to attempt to identify the appropriate key for decrypting the files automatically so that I have as little user intervention as possible. If the key can not be identified (for example, if the recipient(s) are hidden) the application will prompt for the selection of the correct key. I am trying to make it as streamlined as possible.
The RFC suggests the packet is not part of the encrypted data which makes sense. PGP makes it easy to try and identify who encrypted the data. This is evident when you try and decrypt a file using Kleopatra when it has the relevant keys added to its key database. In this instance, it will prompt for the password protecting the secret key.
My specific question is:
How do I use the C# BouncyCastle library to read which recipients the encrypted data was intended to? In otherwords, which private key to use for decryption?
I have tried to find examples using the Bouncy Castle GitHub repository and couldn't see any that demonstrated this particular problem. I also looked at as many google search results for this question to no avail.
I found the answer to my question. I assumed that if it was part of the PGP specification then it must be possible without too much bother. I therefore decided to scrutinise the decryption process and all of the objects used throughout it.
Using the debugger I enumerated the items within the PgpEncryptedDataList and found the key ID for the public key that encrypted it inside the individual PgpPublicKeyEncryptedData object.
The object contains a property of type long called KeyId. This was the value I was looking for to match against the keys stored in the application.
The following snippet is just an example of what I used to reach the KeyId property:
using (var inputFile = File.OpenRead(#"E:\Staging\6114d23c-2595abef\testfile.txt.gpg"))
using (var decoderStream = PgpUtilities.GetDecoderStream(inputFile))
{
var objectFactory = new PgpObjectFactory(decoderStream);
var encryptedList = (PgpEncryptedDataList)objectFactory.NextPgpObject();
foreach (var encryptedData in encryptedList.GetEncryptedDataObjects().Cast<PgpPublicKeyEncryptedData>())
{
var keyId = encryptedData.KeyId.ToString("X");
Console.WriteLine($"Encryption Key ID: {keyId}");
}
}
Setting a breakpoint after the first enumeration you can examine the encryptedData variable and observe something similar to:
So, after all the struggle, it was actually very simple. Accessing the KeyId during the decryption process is then straightforward and you can automagically go and grab the correct private key to do the decryption.
For completeness, it is common for PGP that files are encrypted for more than just one recipient. In this case, you will see more than one encrypted data object. It doesn't mean the data is encrypted twice. Only the session key. The session key is encrypted N number of times where N is the number of recipients. This allows each recipient to be able to decrypt one of the sessions keys and then to go ahead and decrypt the data.
Refer to the image below showing two objects, and as you would expect, two KeyId properties :)
This snippet is from the PgpDecrypt.cs which already looks through the encrypted objects and checks the key identifier against the PgpSecretKeyRingBundle passed in as a parameter:
foreach (PgpPublicKeyEncryptedData pked in encryptedDataList.GetEncryptedDataObjects())
{
privateKey = PgpKeyHelper.FindSecretKey(secretKeyRing, pked.KeyId, passPhrase.ToCharArray());
if (privateKey == null)
{
continue;
}
encryptedData = pked;
break;
}
For anyone wishing to have a head start with PGP, BouncyCastle and C#, please refer to my library which contains a compilation of many PGP functions. The PgpDecrypt class can be changed to automatically incorporate the key discovery as discussed in this question.

how to make validation more safe in wpf desktop app?

In my wpf test program,I have a passwordbox,When user try to login and input a string to passwordbox,how to compare this string with encrypted password to validate user's identity and how to make the this process of comparison more safe.
And my confusion is: Should I decrypt password to plain text then compare with user inputed string directly,like use a equation to confirm whether two variables are equal? I personally think if I do it in this way more secure programming skills should be applied,what is this kinds of skills?
well .. when he types it in, it is in plain text ... but you shouldn't store them as text, you'll usually add a salt and hash them, and keep the salt.
Then you'll do the same with the input, and if both hashes match, you let them log in ...
Example:
Password: BadPassword
You then add a salt (you could use a set one, or generate one, google it up).
let's assume your salt is: YummySalt. you then pass passtord+salt to hashing method: Hash(password+salt).
you'll get some hash, lets say : oanuh835930notihaoneu340
you save that in DB, and when the user enters the password, you generate the salt (or just use the fixed one), hash it, and compare that to the hash in DB.

How to save a password properly

I attemt to write a program, with which you can login to a remote website. For some people having multiple accounts, I try to make it easy for them and store account data in IsolatedStorage. At the current state of my code, the password is just entered in a TextBox and as soon as it's stored converted to a MD5 hash.
Now I'd like to refactor this to proper code, but I got stuck.
A PasswordBox exposes its data through PasswordBox.SecureString and PasswordBox.Password.
So when clicking my save button I'd perform something like
public void OnClick(...)
{
var password = passwordBox.Password;
// store it somehow (e.g. custom MD5 encryption)
var savePassword = passwordBox.SecureString;
// store this string somehow, but how?
}
Here my questions
As soon as I put the plain password from my PasswordBox into var password, is there something visible in memory? Would some hacker be able to make this plain value visible through reflection/debugging? Which code makes these strings actually visible? And what do I need to be aware of?
How to handle SecureString of the PasswordBox?
I'm a bit overwhelmed by all this stuff and I can't figure out the essence of how to handle passwords in an application properly, yet.
I'm not pleading for a whole solution and running code. I'd just be glad, if someone can get me started. And also, I don't want an enterprise solution. I'm just searching for one, which is easy to implement and as save as possible for the effort I put in.
Do you really need the password to be reversible?
A safer way to store it is to salt and hash it.
User: JOHN
Password: (starts out as) myUserPassword667!
Then use some sort of database unique code against the user in the DB. Lets say a GUID.
Now you have abcd-1234-12-1212121ab as the uniquifier for JOHN
so you now have a base password(before hashing)
myUserPassword667!abcd-1234-12-1212121ab
You can now Hash this with one of the SHA or other hashing algorithms in the System.Security namespace.
Now you internally have some Salt that you Apply to your hashing algorithm... (Part of your code only)
MySecretSaltWords559BC
then store the Result as either a Base64 or Binary in your DB.
Ab09l\311sas== (simplified)
Next time the user logs on you find their record in the DB, you get your Unique code that was used when you generated the account and attach to the password they entered.
Hash the entered password with the same technique and binary compare the result, then you don't need to ever store their password. If the hashes don't match you don't have the same password.

Sending messages between two clients, how to verify the identity of the sender?

So assume you have two clients, C1 and C2, each client has a GUID associated with it.
How do you, when you receive a message on C2 that supposedly comes from C1 (by checking the GUID and seeing that it matches the GUID of C1), but since the message is not guaranteed to have come from C1 (C3 might just have sent the message, sending the GUID of C1 in the message header) there has to be some verification that the message actually came from C1.
I've been looking into using asymmetric encryption (RSA) to have C1 send a message that consists of [C1.GUID; RSAEncrypt(C2.PUBLIC_KEY, C1.GUID); MESSAGE], and then let C2 basically do a check like this (python pseudo code):
message.GUID == RSADecrypt(C2.PRIVATE_KEY, message.ENCRYPTED_GUID)
Is this a viable approach? Or is there some other clever/more obvious way to verify the sender of a message?
Assymmetric Algorithms have been invented for such purposes, that's the way digital signatures work.
However, your approach has some problems. Anyone with the public key of the recipient could fake the signature. Also, the signature does not change at all! Anyone intercepting the messages can fake being a valid sender. The purpose of assymetric encryption is to defeat these problems with key exchanges, there's the concept of the digital signature, which is basically an assymetrically encrypted hash of the message you are tossing around.
For RSA, you need to do a bit more in order to create a digital signature from the basic algorithm, see wikipedia for more details: http://en.wikipedia.org/wiki/RSA#Signing_messages
I'd just use a digital signature algorithm from a library. First google search turns up with this for Python:
http://www.example-code.com/python/pythonrsa.asp
http://www.chilkatsoft.com/dsa-python.asp
The problem with this method is that any machine could then capture the guid and rsa-encrypted-guid and pass them just the same. You haven't really created any unique challenge/response criteria that can only be divined by the receiving client. What you would need would be something that is completely unique and can't be gotten simply by looking at passed parameters. Maybe something like:
[ClientName; RSA-ENCRYPTED(GUID+Timestamp); MESSAGE]
In this method, the RSA encryption would be done using Client2's public key so that only Client2's private key could unlock it. Using the ClientName, Client2 could retrieve the expected GUID from a datasource, and then match the returned GUID against the one in the encryption. I incorporated the usage of a timestamp as a salt so that the encrypted string comes out differently each time. It's considered very weak to use a timestamp as a randomization for a salt, but it gets the point across. Other more secure/random algorithms could be implemented.
Anyone spying messages between a client and the server will be able to forge new messages, has client's GUID never change, nor RSA-ENCRYPTED-GUID.
Consider switching to this message model : [GUID; ENCRYPTED_CONTENT_CHECKSUM; CONTENT].
Checksum(message.CONTENT) ==
RSADescrypt(C1.PUBLIC_KEY, message.ENCRYPTED_CONTENT_CHECKSUM)
Still, anyone spying messages can resend previously sent messages.
Public and private keys are the way to go. I will assume you don't care about encrypting the data, but you do care that the data is "authorized".
Lets say you have 3 computers
Comp1
Comp2
Comp3
Lets also say you want Comp1 to send a message to Comp3. you don't care if the message was intercepted, but you do care that it was not forged.
Comp1 will digitally sign the message with its private key
Comp2 will intercept the message from Comp1 to Comp3, but can't change the message without invalidating the signature
Comp2 will forward the message onto Comp3
Comp3 will use Comp1's public key to decrypt the signature and use the hash in the signature to validate the contents.
Now if you want to encrypt the data, you need to add an extra step
Comp1 will digitally sign the message with its private key
Comp1 will generate an random encryption key(typically AES) and encrypt the message.
Comp1 will take that encryption key and encrypt it with Comp3's public key
Comp2 will intercept the message, but cannot read it without Comp3's private key
Comp2 will forward the message onto Comp3
Comp3 will use it's private key to decrypt the AES key
Comp3 will decrypt the entire message using the AES key
Comp3 will validate the message by decrypting the signature with Comp1's public key.
Signature contains a hash of the message, if the hash and the message's hash match, then the data is intact.
You can include the GUIDs in the payload to use as a lookup to decide which public keys to use.
P.S. You will want to use the built in methods to sign a message. Let the Framework do the hashing/etc

Categories