C# Facing issue to encrypt and decrypt text by Base64 - c#

The text ZIRT which i encrypt by base64 this way
public static string encrypt(string ToEncrypt)
{
return Convert.ToBase64String(Encoding.ASCII.GetBytes(ToEncrypt));
}
after encrypt the text becomes V2tsU1ZB and when i try to decrypt using the below function
public static string decrypt(string cypherString)
{
//return Encoding.ASCII.GetString(Convert.FromBase64String(cypherString));
byte[] data = Convert.FromBase64String(cypherString);
string decodedString = Encoding.UTF8.GetString(data);
return decodedString;
}
then i am getting this text WklSVA but it suppose to be ZIRT
Please tell me what is wrong in my code ?
I am giving more code which fail to decrypt text
private void button1_Click(object sender, EventArgs e)
{
string strTxt = "ZIRT";
string ss = EnryptString(strTxt);
string ss1 = EnryptString(ss);
}
public string DecryptString(string encrString)
{
byte[] b;
string decrypted;
try
{
b = Convert.FromBase64String(encrString);
decrypted = System.Text.ASCIIEncoding.ASCII.GetString(b);
}
catch (FormatException fe)
{
decrypted = "";
}
return decrypted;
}
public string EnryptString(string strEncrypted)
{
byte[] b = System.Text.ASCIIEncoding.ASCII.GetBytes(strEncrypted);
string encrypted = Convert.ToBase64String(b);
return encrypted;
}

There is double encoding of the strings that explain the incorrect result. You are also using different text encodings when encrypting and decrypting. ASCII vs UTF8, this should be the same.
The following example provides the result I would expect:
byte[] b = System.Text.ASCIIEncoding.UTF8.GetBytes("test abc");
string base64Encoded = Convert.ToBase64String(b);
b = Convert.FromBase64String(base64Encoded);
Console.WriteLine( System.Text.ASCIIEncoding.UTF8.GetString(b));
// "test abc"
As mentioned in the comments, this is not encryption, but encoding.

Related

Google KMS giving error when decrypting data

When i try to decrypt my data using the Google KMS i am getting this error. Below is my code for the decryption. The error is hitting on the line where there is string plaintext. Thanks in advance
Code
public static string Encrypt(string plaintext)
{
KeyManagementServiceClient client = KeyManagementServiceClient.Create();
//projects/progforthecloudt2020/locations/global/keyRings/pfckeyring001/cryptoKeys/pfckeys
CryptoKeyName kn = CryptoKeyName.FromUnparsed(new
Google.Api.Gax.UnparsedResourceName("GOOGLE RESOURCE ID REMOVED"));
string cipher = client.Encrypt(kn, ByteString.CopyFromUtf8(plaintext)).Ciphertext.ToBase64();
return cipher;
}
public static string Decrypt(string cipher)
{
KeyManagementServiceClient client = KeyManagementServiceClient.Create();
CryptoKeyName kn = CryptoKeyName.FromUnparsed(new Google.Api.Gax.UnparsedResourceName("GOOGLE RESOURCE ID REMOVED"));
string plaintext = client.Decrypt(kn, ByteString.CopyFromUtf8(cipher)).Plaintext.ToBase64();
return plaintext;
}
Error
Grpc.Core.RpcException: 'Status(StatusCode=InvalidArgument, Detail="Decryption failed: the ciphertext is invalid.")'
You’re base64 encoding the result of your encryption call, but then you aren’t base64 decoding it in your decrypt call. You shouldn’t need to base64 encode the data.
public static void Encrypt(string projectId, string locationId, string keyRingId, string cryptoKeyId, string plaintextFile, string ciphertextFile)
{
KeyManagementServiceClient client = KeyManagementServiceClient.Create();
CryptoKeyName cryptoKeyName =
new CryptoKeyName(projectId, locationId, keyRingId, cryptoKeyId);
byte[] plaintext = File.ReadAllBytes(plaintextFile);
EncryptResponse result = client.Encrypt(cryptoKeyName, ByteString.CopyFrom(plaintext));
// Output encrypted data to a file.
File.WriteAllBytes(ciphertextFile, result.Ciphertext.ToByteArray());
Console.Write($"Encrypted file created: {ciphertextFile}");
}
public static void Decrypt(string projectId, string locationId, string keyRingId, string cryptoKeyId, string ciphertextFile, string plaintextFile)
{
KeyManagementServiceClient client = KeyManagementServiceClient.Create();
CryptoKeyName cryptoKeyName =
new CryptoKeyName(projectId, locationId, keyRingId, cryptoKeyId);
byte[] ciphertext = File.ReadAllBytes(ciphertextFile);
DecryptResponse result = client.Decrypt(cryptoKeyName, ByteString.CopyFrom(ciphertext));
// Output decrypted data to a file.
File.WriteAllBytes(plaintextFile, result.Plaintext.ToByteArray());
Console.Write($"Decrypted file created: {plaintextFile}");
}

Throwing an exception when convert string to base64

I have two methods, where I need to convert string to base64 at begin and reverse this operation at the end. Problem is when my input string lenght is not divisible by 4 an conversion method throws exception.
public class Hashing
{
public string Encrypt(string encrypted)
{
byte[] byteData = Convert.FromBase64String(encrypted);
byte[] byteResult = Encrypt(byteData); // pt.1
return Convert.ToBase64String(byteResult);
}
public string Decrypt(string decrypted)
{
byte[] byteData = Convert.FromBase64String(decrypted);
byte[] byteResult = Decrypt(byteData); //pt.2
return Convert.ToBase64String(byteResult);
}
/*
...
*/
}
class Program
{
static void Main(string[] args)
{
Hashing cryptographyContext = new Hashing();
var cryptoTest = "123456789"; //someStringThatNotGonnaBeConverted;
string enc = cryptographyContext.Encrypt(password);
string dec = cryptographyContext.Decrypt(enc);
Console.WriteLine(dec);
Console.ReadLine();
}
}
Problem is I need base64 format at input of Decrypt and Encrypt methods (these at pt. 1 and 2) And I need returning strings from these methods. Do someone have an idea how to workaround this behaviour?
You are using base-64 incorrectly; base-64 translates:
forwards, arbitrary byte[] to structured string
backwards, structured string to the original byte[]
Conversely, a regular text encoding works the other way:
forwards, arbitrary string to structured byte[]
backwards, structured byte[] to the original string
You are trying to use base-64 to get a byte[] from an arbitrary string, which isn't a thing that it does. For that, you want a regular text encoding, such as UTF-8. Try using Encoding.UTF8.GetBytes() etc instead for one half, and base-64 for the other:
public string Encrypt(string plainText)
{
byte[] byteData = Encoding.UTF8.GetBytes(plainText);
byte[] byteResult = Encrypt(byteData);
return Convert.ToBase64String(byteResult);
}
public string Decrypt(string cipherText)
{
byte[] byteData = Convert.FromBase64String(cipherText);
byte[] byteResult = Decrypt(byteData);
return Encoding.UTF8.GetString(byteResult);
}

Base64 and SHA256 results of C# and Python are different

I'm a newcomer and beginner, because my English is not good, I will make a long story short, please help me.
A public key is Base64 decode and SHA256.
Use C# and Python (Python result is correct.)
Why do I get different results?
If you like, I hope to get the answer by C# code(my English is very poor.)
Thank you very much.
Same public key : MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0k9N59vMq/1BP6lwgyxVPeWj6EFTMW+wJqyl+vePi1vKzJBCXWPZ5Ls7PmNaTaAQ5TVC5WVoxveuvaYLGm514Y7EDTrL8BrPWcK73Gw7E/IQyfOC+/Mw6mBnANyWiVAu9qIi2/PWasA2J/XR97kfUfuM716NKUNzBmmju8pfyPu+ee9Zfh0fUclF0g48AJMZaw8g6SxiWnQ8XhABkMHXyqVio5cdt5omupDcZ17HHBXsP3KHNX5Tu8ZDrCbFH566p1WGjM6W2Wr2YffzC8WPyFTS/6eiAde5iVjS2VHqRkmgQvrH794kGUC7ZUitP7p6gYCvhdffqxLQslvga9cPNQIDAQAB
Base64 decode ==> SHA256
Python:
pubkey_der = base64.b64decode(pubKey)
sha = hashlib.sha256(pubkey_der).hexdigest()
for i in sha:
print(i),
print('\n'),
result:890e947269d4e6d9c73883157f65aa6f12e20ad0a05ff518b5f9cb43cea28b89
C#:
private void button_go2_Click(object sender, EventArgs e)
{
string b64 = DecodeBase64(pubKey);
string result = GetSHA256HashFromString(b64);
}
private static string DecodeBase64(string pubKey)
{
string decode = string.Empty;
byte[] bytes = Convert.FromBase64String(pubKey);
decode = Encoding.UTF8.GetString(bytes);
return decode;
}
public string GetSHA256HashFromString(string strData)
{
byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(strData);
try
{
SHA256 sha256 = new SHA256CryptoServiceProvider();
byte[] retVal = sha256.ComputeHash(bytValue);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
catch (Exception ex)
{
throw new Exception("GetSHA256HashFromString() fail,error:" + ex.Message);
}
}
result:1eb61f3f380bccf54e61e05cdbe6e14c3871c6c827b33dc03b2cf47c1fc0df4c

RSA encrypt by PHP and decrypt by C#

I'm trying to encryption and decrpytion process between C# and PHP.
My C# code:
this.EncryptData("123456", 1024, this.PublicKey);
public byte[] Encrypt(byte[] byte_0, int keysize, string publicKey)
{
byte[] numArray;
using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider(keysize))
{
rSACryptoServiceProvider.FromXmlString(publicKey);
numArray = rSACryptoServiceProvider.Encrypt(byte_0, this.bool_0);
}
return numArray;
}
public string EncryptData(string string_0, int keysize, string publicKey)
{
string base64String;
try
{
byte[] numArray = this.Encrypt(Encoding.UTF8.GetBytes(string_0), keysize, publicKey);
base64String = Convert.ToBase64String(numArray);
}
catch (Exception exception)
{
base64String = string.Empty;
}
return base64String;
}
public byte[] Decrypt(byte[] byte_0, int keysize, string Key)
{
byte[] numArray;
using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider(keysize))
{
rSACryptoServiceProvider.FromXmlString(Key);
numArray = rSACryptoServiceProvider.Decrypt(byte_0, this.bool_0);
}
return numArray;
}
public string DecryptData(string string_0, int keysize, string Key)
{
string str;
try
{
byte[] numArray = this.Decrypt(Convert.FromBase64String(string_0), keysize, Key);
str = Encoding.UTF8.GetString(numArray);
}
catch (Exception exception)
{
str = string.Empty;
}
return str;
}
and my PHP: lib(https://github.com/membersuite/sdk-php/blob/master/APISample/SSOWithSDK/phpseclib/Crypt/RSA_XML.php)
$rsa = new Crypt_RSA_XML();
$plaintext = '123456';
$rsa->loadKeyfromXML($publicKey);
$ciphertext = base64_encode(strrev($rsa->encrypt($plaintext)));
code after PHP encrypt cant decrypt by c# code. anyone can help?
Although Microsoft uses little endian notation for numbers, RSA has been defined by PKCS#1 / RFC 3447. That explicitly defines how to do padding and such, but it also defines how the resulting octet string should look like using I2OSP or the integer-to-octet-string primitive. This primitive specifies the output as fixed size (key size) byte array in big endian format. This is also the encoding that PHP uses, so you should not reverse the output.
In other words, you should not have to use strrev.

Bad data exception when decrypting using RSA with correct private and public key pair in C#

This is my code for decryption process:
private RSACryptoServiceProvider _rsa;
private string _privateKey;
private string _publicKey;
public RsaLibrary()
{
//initialsing the RSA object taking the option of a 1024 key size
_rsa = new RSACryptoServiceProvider(1024);
_privateKey = _rsa.ToXmlString(true);
_publicKey = _rsa.ToXmlString(false);
}
public string Decrypt(string ciphertext, string privateKey_ = null)
{
if (String.IsNullOrEmpty(privateKey_))
{
return DecryptToBytes(ciphertext, _privateKey);
}
else
{
return DecryptToBytes(ciphertext, privateKey_);
}
}
private string DecryptToBytes(string ciphertext, string privateKey)
{
if (String.IsNullOrEmpty(privateKey))
{
throw new ArgumentNullException("Error: No key provided.");
}
if (ciphertext.Length<=0)
{
throw new ArgumentNullException("Error: No message to decrypt.");
}
byte[] plaintext;
byte[] ciphertext_Bytes = Encoding.Unicode.GetBytes(ciphertext);
_rsa.FromXmlString(privateKey);
plaintext = _rsa.Decrypt(ciphertext_Bytes, false);
return Encoding.Unicode.GetString(plaintext);
}
The encryption code:
private string EncryptToByte(string plaintext, string publicKey)
{
if (String.IsNullOrEmpty(publicKey))
{
throw new ArgumentNullException("Error: No key provided.");
}
if (plaintext.Length<=0)
{
throw new ArgumentNullException("Error: No message to incrypt");
}
byte[] ciphertext;
byte[] plaintext_Bytes = Encoding.Unicode.GetBytes(plaintext);
_rsa.FromXmlString(publicKey);
ciphertext = _rsa.Encrypt(plaintext_Bytes, false);
return Convert.ToBase64String(ciphertext);
}
I can not see where I am going wrong. I have made sure that the keys are correct. The public one which i extracted using this line in the constructor:
_publicKey = _rsa.ToXmlString(false);
This public key is displayed on the form that I created. The private i used the "true" instead of false.
Any ideas?
Ciphertext is very unlikely to be genuinely UTF-16-encoded text. Assuming that the encryption side had something like:
string encryptedText = Encoding.Unicode.GetString(encryptedBytes);
you've basically lost data. The result of encryption is not text - it's arbitrary binary data. If you want to convert that to text for some transport reason, you should use Base64, e.g.
string base64EncryptedText = Convert.ToBase64String(encryptedBytes);
Then use Convert.FromBase64String to recover the original encrypted binary data which is ready to decrypt.

Categories

Resources