Invalid length for a Base-64 char array - c#

I trying to Decrypt password in visual studio 2010 using C-Sharp language but i m stuck on this error i try all the solution which was provided on this side but my error not resolved how i encrypt password can anybody tell me using MD5 my code is,Now it gives another error "String reference not set to an instance of a String.*Parameter name: s" What can i do i cant understand .I m newbie on C#*.I dont know what can i do if i waste your time then sorry to all.
public string PasswordDecrypt(string sQueryString)
{
byte[] buffer;
TripleDESCryptoServiceProvider loCryptoClass = new
TripleDESCryptoServiceProvider();
MD5CryptoServiceProvider loCryptoProvider = new MD5CryptoServiceProvider();
try
{
buffer = Convert.FromBase64String(sQueryString);
loCryptoClass.Key = loCryptoProvider.ComputeHash(ASCIIEncoding.ASCII.GetBytes(sQueryString));
loCryptoClass.IV = lbtVector;
return ASCIIEncoding.ASCII.GetString(loCryptoClass.CreateDecryptor().TransformFinalBlock(buffer, 0, buffer.Length));
}
catch (Exception ex)
{
throw ex;
}
finally
{
loCryptoClass.Clear();
loCryptoProvider.Clear();
loCryptoClass = null;
loCryptoProvider = null;
}
}

The code relevant to your question is this:
string sQueryString = txtPassword.Text;
byte[] buffer = Convert.FromBase64String(sQueryString);
Create a test case for this, containing the data as is entered when you get the error. Perhaps your users don't input their password as base64.

I think you are confused about what to do for password security. Passwords don't get encrypted, they get hashed. That's kind of a one-way-encryption. The same password will always result in the same hash, but different passwords are allowed to generate the same hash, so it's impossible to decrypt it from hash to password.
While that doesn't sound useful at first, the point is that you never actually store the password, encrypted or not. You store the hash value of the password. That way you know when someone enters a password, it gets hashed and matches the stored hash, it's the correct password... without ever knowing what the password was.
So you cannot decrypt a hash. You simply hash your input and compare with an earlier hash from the correct password.
Please note that you should also google Salting hashes, a technique for lowering the attack surface of hashes once the data store was breached and the hash is known to potential attackers.

Related

How to prevent the encrypted (AES) data from being tampered with?

I want to encrypt the data (AES) after saving it to the database and decrypt it when reading. How can I prevent data from being tampered with in the database? My algorithm is improved from https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx.
I have tested, in the encrypted ciphertext casually add "a", decryption will throw an exception(The padding is invalid and is not removed), add any charactor,will throw an exception?there is no such possibility: do not throw an exception, you can decrypt, but the result is not the original data
string original = "getABEDKK";
string password = "123456kfjsEYR+*j";
string cipherText = Encrypt(original, password);
MessageBox.Show("After encrypt:"+cipherText);
string plainText = Decrypt("a"+cipherText, password);
MessageBox.Show("After decrypt:" + plainText);
Add something like a checksum or validation field. Then add a layer to the encryption that decrypts the data, checks the validation and throws an exception if the validation field is not correct.

PFX Self Signed x509 Certificate with password secure

After looking at how to generate self-signed digital signatures from Creating a self-signed certificate in C#, I can call CreateSelfSignCertificatePfx and get PXF data in a byte array back, which can then be used within an X509Certificate2 object to sign and verify. Example...
byte[] pfx = Certificate.CreateSelfSignCertificatePfx("O=Company,CN=Firstname,SN=Lastname", DateTime.Now, DateTime.Now.AddYears(1), "password");
X509Certificate2 cert = new X509Certificate2(pfx, "password");
byte[] publicBytes = cert.RawData;
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
byte[] signedData = rsa.SignData(new System.Text.UTF8Encoding().GetBytes("Test"), new SHA1CryptoServiceProvider());
RSACryptoServiceProvider rsa2 = (RSACryptoServiceProvider)new X509Certificate2(publicBytes).PublicKey.Key;
bool verified = rsa2.VerifyData(new System.Text.UTF8Encoding().GetBytes("Test"), new SHA1CryptoServiceProvider(), signedData);
This works. My concern though is the original bytes, byte[] pfx from above, need to be stored in a DB (to sign stuff). The question becomes, how secure are the bytes in this format? I know you need the password to construct the new X509Certificate2 with a private key, but in a general sense, how secure are the bytes without the password? I have no problems encrypting these bytes as an added layer, but is that necessary?
According to X509Certificate2.X509Certificate2(Byte[], String) Constructor
Calling this constructor with the correct password decrypts the private key and saves it to a key container.
I just want to ensure the private key is safe without the password.
In my eyes the question is not whether you should put the "bytes" in the database, but more, would you put the file with the private key in your file system.
In the way you're doing it, it's essentially the same thing. You're just storing the bytes that make up the cert file.
I may be failing to understand the difference here, but they bytes and the file are essentially the same thing, the only difference being the fact that one has to gain access to the db to get them.
Use a smartcard or token to store your private key.
UPDATE:
The Pvt key can be accessed by anyone who can access the machine.
The private keys in a PFX (PKCS#12) are stored encrypted, which is of course what the password is for. Not all of a PFX is encrypted, the structural pieces stay plaintext to contain metadata about the contents (like what encryption algorithm was used).
Based on inspecting the file, as of Windows 7 the private keys are encrypted using 3-key (168-bit) 3DES. The key is derived via a complex formula involving your password; there's nothing saved in the file which gives any indication as to what your password was, how long it was, et cetera.
The password is usually proven correct by the addition of a MAC on the contents, which uses the same password for its key derivation function. In the possible case of the MAC password and the encryption password being different (which I've personally never seen) the password is verified by the structural information in the encrypted payload.
DES' weakness mainly lay in the small keysize, it's easily brute forcable today. A 3-key 3DES key has 112 more semantic bits than a (1)DES key, making it take 2^112 (~5 x 10^33) times longer to break.
So, at the end of the day, the private key is cryptographically sound. But like anything with a password-based input, if you use a bad password that is easily guessed then it can be cracked by brute force.

Trying to Encrypt/Decrypt using AES. Progress == null;

Edit.
I guess I had a problem with creating a correct input into the encrypt/decrypt methods: These lines of code do the trick:
string encrypted = en.Encrypt(stringBuilder.ToString(), "username", "password");
string decrypted = en.Decrypt(encrypted, "username", "password");
mainWindow.ChangeTextBox = encrypted + Environment.NewLine + decrypted;
I am just playing around and trying to figure out how encryption/decryption by using AES works. I am referring to this article (pretty much copy and paste :( Trying to learn).
There they give me complete encryption/decryption methods which I have tried to modify. I am trying to pass a list of entries created by ArrayList then binded with string builder. It seems like I am able to encrypt data but decryption causes error:
Length of the data to decrypt is invalid.
at line with code:
ByteCount = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length);
How can I implement this code to be useful with my program and work correctly?
Regards.
I haven't looked through the code in detail, but it seems that the order of the parameters on the calls to Encrypt and Decrypt doesn't match the definition of the methods. In the calls to these methods you appear to have username, password, plain/cyphertext; whereas the methods have the signature plain/cyphertext, password, username.
Am I right it's caused for an empty or null string as plaintext? ;-)
"lol1" can not be decrypted as it's not a valid ciphertext length (padding!) not to say it wouldn't make any sense.

Force to decrypt file with wrong key - C# + Bouncy Castle

I'm writing a simple application where users can encrypt/decrypt files using one of the block algorithms like Rijndael. I have to encrypt the session key as well with the same algorithm and store it together with the cipher text in an xml file. The key used for session key encryption is a SHA256 hash of the user's password. The result is something like:
<File>
<EncryptedKey>session key encrypted with user's password hash</EncryptedKey>
<Data>Data encrypted with session key</Data>
</File>
While decrypting, user is asked to type the password, then the hash is generated and used as a key to decrypt EncryptedKey from xml file and then the session key can be used to decrypt the data.
It works when user types correct password, but I want the application to decrypt file even if the password is wrong. I'm using Bouncy Castle and now when password is wrong (so the session key is wrong either), it throws an Exception "Pad block corrupted". I don't want to display any message boxes informing that an error occurs. Instead, I want to decrypt the file anyway and just save garbage as a result. Is that possible? My code for decrypting:
IBufferedCipher cipher = CipherUtilities.GetCipher("Rijndael/ECB/PKCS7Padding");
KeyParameter par = new KeyParameter(generateHash(password));
cipher.Init(false, par);
byte[] output = cipher.DoFinal(data); // Exception here when password is wrong
I also tried to use ProcessBytes() method first and DoFinal() at the end, but it didn't work either.
That pretty well defies the point of encryption in the first place. Presumably you could catch the exception and, in your catch block, write junk data (maybe a Hex dump of the exception stack?) to a file- but why? As noted by Ramhound, that would give a malicious user data which could be used in a brute-force attack to compare with when they have successfully decrypted the file.
I would go back to the assumptions/design phase of this: why do you want to avoid showing a message which states "The password provided did not match the expected password. Please re-enter. 3 Tries Remain." (or whatever)? What is gained by outputting a "junk" file?

ASP.NET: SHA1 + Salt Password Hashing on Multiple Servers

So, I am the approach David Hayden posted on his blog (http://davidhayden.com/blog/dave/archive/2004/02/16/157.aspx) to create a salt and hash the user's password by taking the user's raw password and the generated salt and using SHA1 to hash the value.
I then store the salt and the hashed password in the database.
The website is currently load balanced, so I was wondering if resulting hash value would be the same for both servers.
Here is the snippet of code posted on David Hayden's blog:
private static string CreateSalt(int size)
{
//Generate a cryptographic random number.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[size];
rng.GetBytes(buff);
// Return a Base64 string representation of the random number.
return Convert.ToBase64String(buff);
}
private static string CreatePasswordHash(string pwd, string salt)
{
string saltAndPwd = String.Concat(pwd, salt);
string hashedPwd =
FormsAuthentication.HashPasswordForStoringInConfigFile(
saltAndPwd, "sha1");
return hashedPwd;
}
The reason I ask is that this code uses the code snippet:
FormsAuthentication.HashPasswordForStoringInConfigFile(
saltAndPwd, "sha1");
I think the key question your asking here is if the SHA1 algorithm is the same whatever server it is running on. In which case the answer is yes.
Presumably you store your generated salt somewhere that all the servers can access it, along with the password hash? So the method used to generate the salt doesn't need to be consistent across servers.
This method will only use the parameters passed into it.
Don't worry about it; it will work.
"To address this issue, the validationKey and decryptionKey values must be identical on all computers in the Web farm."
http://msdn.microsoft.com/en-us/library/ff647070.aspx#pagexplained0002_webfarmscenarios

Categories

Resources