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

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.

Related

How to decrypt an OpenPGP RSA Encrypted text file in C#?

I am hoping that this question can be met with some guidance for someone who is beginning to work with encryption/decryption in C#. There are existing examples on the web regarding this, but I am truthfully struggling to put it all into practice for my given situation.
If given a text file that has been encrypted using OpenPGP with RSA, what is the best method to decrypt this in C#?
This is what I am attempting:
Using Kleopatra OpenPGP, I am generating a key pair using 2048bit RSA. This generates a private and public key.
I am then encrypting/signing a text file with a few word in it as a test.
In C#, I want to decrypt this text file.
Current code:
byte[] encryptedData = File.ReadAllBytes("C:\\PGP Encryption\\test.txt.gpg"); // The encrypted text file generated by Kleopatra.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
//Import the RSA Key information. This needs
//to include the private key information.
RSA.ImportParameters(RSAKeyInfo);
//Decrypt the passed byte array and specify OAEP padding.
decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
}
return decryptedData;
Unfortunately, the RSA.Decrypt() call throws an exception that reads "The data to be decrypted exceeds the maximum for this modulus of 128 bytes."
I also do not believe that my private key is actually being loaded, as I'm not explicitly stating where the key is. But I don't see how the RSAParameters object is supposed to get populated otherwise.
If anyone can point me in the right direction to decrypt a file in this way, thank you in advance for your time and information.
It's looks like you need this library (see Decrypt section) https://github.com/mattosaurus/PgpCore

C# rsa decryption intermittent failure [duplicate]

This question already has an answer here:
RSA Encryption and Decryption successed in JS, but Decryption fails in C#
(1 answer)
Closed 3 years ago.
I have the following implementation for decrypting a value. This implementation works, but in some small case the values I'm attempting to decrypt are throwing a Cryptographic Exception, with the message 'The Parameter is incorrect'. This occurs where I call the Decrypt method on the private key below.
All values are encrypted with the public key, base64 encoded in transit, and passed along to this method the same way, so I don't understand why it would be blowing up sometimes. If I re-encrypt with the public key, that new value can usually be unencrypted successfully.
Certificate in this case below is the X509Certificate2
public string Decrypt(CertificateType certificateType, byte[] encryptedString)
{
string result = null;
var certificate = GetCertificate(certificateType);
var privateKey = certificate?.GetRSAPrivateKey();
if (privateKey != null)
{
var decryptedBytes = privateKey.Decrypt(encryptedString, RSAEncryptionPadding.Pkcs1);
result = Encoding.Default.GetString(decryptedBytes);
}
return result;
}
Any ideas as to what would cause that exception?
You should run it 1000x and log all the errors, see what those base64 input strings have in common and what the passing ones do - my guess is that it's padding related with the base64 encoding (Some encoders will pad with equal signs at the end of the strings and some won't, then some decoders expect the padding and some are able to handle it). When it lines up right, the decrypt works, when it doesn't (the length of the base64 string) the method throws an exception.
Other alternative is that instead of base64, you should be doing base64url encoding. When it works, it's because base64(x) == base64url(x) and when it doesn't it's because base64(x) != base64url(x)
Looks like it is with the Base64 encoding. Thank you for the help!
The Answer on this post did remove the decrypt issue I was having:
RSA Encryption and Decryption successed in JS, but Decryption fails in C#

Invalid length for a Base-64 char array

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.

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?

Categories

Resources