error when decrypt data - c#

I use RSA cryptography to Enc/Dec message
Encryption is work well but when Decrypting I got This error on this line .
rsa.Decrypt(dataByte, false);
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Security.Cryptography.CryptographicException: The parameter is incorrect.
code is:
string en= x509_Encrypt(Current_Record_Hmac, PFXFile, s_pass);
string de= ByteToString( X509_Decrypt(en, PFXFile, s_pass));
public static byte[] X509_Decrypt(string data, string certificateFile, string password)
{
var dataArray = data.Split(new char[] { ',' });
byte[] dataByte = new byte[dataArray.Length];
for (int i = 0; i < dataArray.Length; i++)
{
dataByte[i] = Convert.ToByte(dataArray[i]);
}
X509Certificate2 cert = new X509Certificate2(certificateFile, password);
var rsa = new RSACryptoServiceProvider();
var x509_privateKey = cert.PrivateKey;
string pri = x509_privateKey.ToString();
string x509_privateKey_ToString = x509_privateKey.ToString();
string X509_publicKey = ByteToString(cert.GetPublicKey());
x509_privateKey_ToString = rsa.ToXmlString(true);
X509_publicKey = rsa.ToXmlString(false);
rsa.FromXmlString(x509_privateKey_ToString);
var decryptedByte = rsa.Decrypt(dataByte, false);
return (decryptedByte);
}
public string x509_Encrypt(string input, string certificateFile, string password)
{
var dataToEncrypt = _encoder.GetBytes(input);
var encoding = new System.Text.ASCIIEncoding();
X509Certificate2 cert = new X509Certificate2(certificateFile, password);
var x509_privateKey = cert.PrivateKey;
string x509_privateKey_ToString = ByteToString(encoding.GetBytes(x509_privateKey.ToString()));
string X509_publicKey = ByteToString(cert.GetPublicKey());
//Encrypting the text using the public key
RSACryptoServiceProvider cipher = new RSACryptoServiceProvider();
x509_privateKey_ToString = cipher.ToXmlString(true);
X509_publicKey = cipher.ToXmlString(false);
cipher.FromXmlString(X509_publicKey);
var encryptedByteArray = cipher.Encrypt(dataToEncrypt, false).ToArray();
var length = encryptedByteArray.Count();
var item = 0;
var sb = new StringBuilder();
foreach (var x in encryptedByteArray)
{
item++;
sb.Append(x);
if (item < length)
sb.Append(",");
}
return sb.ToString();
}

Try this for your decrypt method:
public string X509_Decrypt(string inputString, string pathToCertFile, string password)
{
if (inputString == null)
{
return null;
}
X509Certificate2 certificate = new X509Certificate2(pathToCertFile, password, X509KeyStorageFlags.MachineKeySet);
try
{
var cryptoProvider = (RSACryptoServiceProvider)certificate.PrivateKey;
int dwKeySize = cryptoProvider.KeySize;
int blockSize = ((dwKeySize / 8) % 3 != 0) ? (((dwKeySize / 8) / 3) * 4) + 4 : ((dwKeySize / 8) / 3) * 4;
int iterations = inputString.Length / blockSize;
var arrayList = new ArrayList();
for (int i = 0; i < iterations; i++)
{
byte[] encryptedBytes = Convert.FromBase64String(
inputString.Substring(blockSize * i, blockSize));
Array.Reverse(encryptedBytes);
arrayList.AddRange(cryptoProvider.Decrypt(encryptedBytes, true));
}
return Encoding.UTF32.GetString(arrayList.ToArray(Type.GetType("System.Byte")) as byte[]);
}
catch (Exception ex)
{
throw new SystemException(ex.Message);
}
}
And try this for your encrypt message:
public string X509_Encrypt(string inputString, string pathToCertFile, string password)
{
if (inputString == null)
{
return null;
}
X509Certificate2 certificate = new X509Certificate2(pathToCertFile, password, X509KeyStorageFlags.MachineKeySet);
try
{
// TODO: Add Proper Exception Handlers
var rsaCryptoServiceProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key;
int keySize = rsaCryptoServiceProvider.KeySize / 8;
byte[] bytes = Encoding.UTF32.GetBytes(inputString);
int maxLength = keySize - 42;
int dataLength = bytes.Length;
int iterations = dataLength / maxLength;
var stringBuilder = new StringBuilder();
for (int i = 0; i <= iterations; i++)
{
var tempBytes = new byte[ (dataLength - maxLength * i > maxLength) ? maxLength : dataLength - maxLength * i];
Buffer.BlockCopy(bytes, maxLength * i, tempBytes, 0, tempBytes.Length);
byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt(tempBytes, true);
Array.Reverse(encryptedBytes);
stringBuilder.Append(Convert.ToBase64String(encryptedBytes));
}
return stringBuilder.ToString();
}
catch (Exception ex)
{
throw new SystemException(ex.Message);
}
}

You cannot just convert bytes to characters like that. If you want to transmit the ciphertext as a string you need to use an encoding such as base 64 encoding and decode before decryption.

Related

Decryption Exception - length of the data to decrypt is invalid When add more data

I am trying to decrypt that from the database. The Data is encrypted from the SQL Server
reportItems.DisabilityGroup = Cryptography.ASPEncrypter(reportItems.DisabilityGroup, true);
The above code is when I invoke the decryption method. It works for small data but fails for more data. I get the following order
System.Security.Cryptography.CryptographicException: 'Length of the data to decrypt is invalid.'
private static string DoEncrypt(string Message)
{
// Encrypt string
byte[] Results;
var UTF8 = new UTF8Encoding();
using (var HashProvider = new MD5CryptoServiceProvider())
{
var TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(PassPhrase));
//var TDESAlgorithm = new TripleDESCryptoServiceProvider()
//{
// Key = TDESKey,
// Mode = CipherMode.ECB,
// Padding = PaddingMode.PKCS7
//};
using (var TDESAlgorithm = new TripleDESCryptoServiceProvider())
{
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
if (Message == null)
return "";
var DataToEncrypt = UTF8.GetBytes(Message);
try
{
var Encryptor = TDESAlgorithm.CreateEncryptor();
Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
}
finally
{
TDESAlgorithm.Clear();
HashProvider.Clear();
}
}
}
return Convert.ToBase64String(Results);
}
private static string DoDecrypt(string Message)
{
// Decrypt string
byte[] Results;
var UTF8 = new UTF8Encoding();
using (var HashProvider = new MD5CryptoServiceProvider())
{
var TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(PassPhrase));
using (var TDESAlgorithm = new TripleDESCryptoServiceProvider())
{
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
//var DataToDecrypt = Convert.FromBase64String(Message);
var DataToDecrypt = new byte[0];
if (!IsBase64String(Message, out DataToDecrypt))
{
return Message;
}
try
{
var Decryptor = TDESAlgorithm.CreateDecryptor();
Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
}
finally
{
TDESAlgorithm.Clear();
HashProvider.Clear();
}
}
}
return UTF8.GetString(Results);
}
public static bool IsBase64String(string base64String, out byte[] bytes)
{
bytes = null;
if (string.IsNullOrEmpty(base64String) || base64String.Length % 4 != 0
|| base64String.Contains(" ") || base64String.Contains("\t") || base64String.Contains("\r") || base64String.Contains("\n"))
return false;
try
{
bytes = Convert.FromBase64String(base64String);
return true;
}
catch (Exception)
{
// Handle the exception
}
return false;
}
public static string ASPEncrypter(string PriorValue, bool Decrypt)
{
// Public function to encrypt/decrypt string
if (String.IsNullOrWhiteSpace(PriorValue))
return "";
var Result = string.Empty;
if (Decrypt)
Result = DoDecrypt(PriorValue);
else
Result = DoEncrypt(PriorValue);
return Result;
}

How to sign a string with rsa-sha256 by using private key?

I have to sign a string with privateKey generated by OpenSSL on each API call, the privateKey is received from a database and changes for each user.
I've read that I should use RSACryptoService and add privateKey as parameter to achieve this. However I get error "Invalid data" in ImportParameters
This is the code:
string privateKey = "-----BEGIN RSA PRIVATE KEY-----
MIIJ....."
RSAParameters rsap = new RSAParameters
{
Modulus = Encoding.ASCII.GetBytes(privateKey)
};
rsa.ImportParameters(rsap);
byte[] encryptedData = rsa.Encrypt(Encoding.UTF8.GetBytes(StringToSign), false);
string base64Encrypted = Convert.ToBase64String(encryptedData);
In the documentation of the service it is stated that it is required to sign the string with RSA-SHA256. Here is the code to sign that string in Node.JS:
const signature = crypto.createSign('RSA-SHA256').update(string).sign(privateKey, 'base64')
However, I wasn't able to find anything similar in c#.
In the linked answer by #SmileDeveloper How to read a PEM RSA private key from .NET there was linked the source for OpenSSLKey and by reusing some of functions linked in the source code i managed to sign my string by using my PEM privateKey as string to sign another string.
The used code to do so is the following:
// encoding my privateKey from string to byte[] by using DecodeOpenSSLPrivateKey function from OpenSSLKey source code
byte[] pemprivatekey = DecodeOpenSSLPrivateKey(privateKey);
// enconding my string to sign in byte[]
byte[] byteSign = Encoding.ASCII.GetBytes(Sign);
// using DecodeRSAPrivateKey function from OpenSSLKey source code to get the RSACryptoServiceProvider with all needed parameters
var rsa = DecodeRSAPrivateKey(pemprivatekey);
// Signing my string with previously get RSACryptoServiceProvider in SHA256
var byteRSA = rsa.SignData(byteSign, CryptoConfig.MapNameToOID("SHA256"));
// As required by docs converting the signed string to base64
string Signature = Convert.ToBase64String(byteRSA);
While here are all the functions reused from OpenSSLKey used above:
public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
MemoryStream mem = new MemoryStream(privkey);
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
int elems = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return null;
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
return null;
bt = binr.ReadByte();
if (bt != 0x00)
return null;
//------ all private key components are Integer sequences ----
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
D = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
P = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
Q = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DP = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DQ = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = MODULUS;
RSAparams.Exponent = E;
RSAparams.D = D;
RSAparams.P = P;
RSAparams.Q = Q;
RSAparams.DP = DP;
RSAparams.DQ = DQ;
RSAparams.InverseQ = IQ;
RSA.ImportParameters(RSAparams);
return RSA;
}
catch (Exception)
{
return null;
}
finally
{
binr.Close();
}
}
public static byte[] DecodeOpenSSLPrivateKey(String instr)
{
const String pemprivheader = "-----BEGIN RSA PRIVATE KEY-----";
const String pemprivfooter = "-----END RSA PRIVATE KEY-----";
String pemstr = instr.Trim();
byte[] binkey;
if (!pemstr.StartsWith(pemprivheader) || !pemstr.EndsWith(pemprivfooter))
return null;
StringBuilder sb = new StringBuilder(pemstr);
sb.Replace(pemprivheader, ""); //remove headers/footers, if present
sb.Replace(pemprivfooter, "");
String pvkstr = sb.ToString().Trim(); //get string after removing leading/trailing whitespace
try
{ // if there are no PEM encryption info lines, this is an UNencrypted PEM private key
binkey = Convert.FromBase64String(pvkstr);
return binkey;
}
catch (System.FormatException)
{ //if can't b64 decode, it must be an encrypted private key
//Console.WriteLine("Not an unencrypted OpenSSL PEM private key");
}
StringReader str = new StringReader(pvkstr);
//-------- read PEM encryption info. lines and extract salt -----
if (!str.ReadLine().StartsWith("Proc-Type: 4,ENCRYPTED"))
return null;
String saltline = str.ReadLine();
if (!saltline.StartsWith("DEK-Info: DES-EDE3-CBC,"))
return null;
String saltstr = saltline.Substring(saltline.IndexOf(",") + 1).Trim();
byte[] salt = new byte[saltstr.Length / 2];
for (int i = 0; i < salt.Length; i++)
salt[i] = Convert.ToByte(saltstr.Substring(i * 2, 2), 16);
if (!(str.ReadLine() == ""))
return null;
//------ remaining b64 data is encrypted RSA key ----
String encryptedstr = str.ReadToEnd();
try
{ //should have b64 encrypted RSA key now
binkey = Convert.FromBase64String(encryptedstr);
}
catch (System.FormatException)
{ // bad b64 data.
return null;
}
//------ Get the 3DES 24 byte key using PDK used by OpenSSL ----
SecureString despswd = GetSecPswd("Enter password to derive 3DES key==>");
//Console.Write("\nEnter password to derive 3DES key: ");
//String pswd = Console.ReadLine();
byte[] deskey = GetOpenSSL3deskey(salt, despswd, 1, 2); // count=1 (for OpenSSL implementation); 2 iterations to get at least 24 bytes
if (deskey == null)
return null;
//showBytes("3DES key", deskey) ;
//------ Decrypt the encrypted 3des-encrypted RSA private key ------
byte[] rsakey = DecryptKey(binkey, deskey, salt); //OpenSSL uses salt value in PEM header also as 3DES IV
if (rsakey != null)
return rsakey; //we have a decrypted RSA private key
else
{
Console.WriteLine("Failed to decrypt RSA private key; probably wrong password.");
return null;
}
}
private static byte[] GetOpenSSL3deskey(byte[] salt, SecureString secpswd, int count, int miter)
{
IntPtr unmanagedPswd = IntPtr.Zero;
int HASHLENGTH = 16; //MD5 bytes
byte[] keymaterial = new byte[HASHLENGTH * miter]; //to store contatenated Mi hashed results
byte[] psbytes = new byte[secpswd.Length];
unmanagedPswd = Marshal.SecureStringToGlobalAllocAnsi(secpswd);
Marshal.Copy(unmanagedPswd, psbytes, 0, psbytes.Length);
Marshal.ZeroFreeGlobalAllocAnsi(unmanagedPswd);
//UTF8Encoding utf8 = new UTF8Encoding();
//byte[] psbytes = utf8.GetBytes(pswd);
// --- contatenate salt and pswd bytes into fixed data array ---
byte[] data00 = new byte[psbytes.Length + salt.Length];
Array.Copy(psbytes, data00, psbytes.Length); //copy the pswd bytes
Array.Copy(salt, 0, data00, psbytes.Length, salt.Length); //concatenate the salt bytes
// ---- do multi-hashing and contatenate results D1, D2 ... into keymaterial bytes ----
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = null;
byte[] hashtarget = new byte[HASHLENGTH + data00.Length]; //fixed length initial hashtarget
for (int j = 0; j < miter; j++)
{
// ---- Now hash consecutively for count times ------
if (j == 0)
result = data00; //initialize
else
{
Array.Copy(result, hashtarget, result.Length);
Array.Copy(data00, 0, hashtarget, result.Length, data00.Length);
result = hashtarget;
//Console.WriteLine("Updated new initial hash target:") ;
//showBytes(result) ;
}
for (int i = 0; i < count; i++)
result = md5.ComputeHash(result);
Array.Copy(result, 0, keymaterial, j * HASHLENGTH, result.Length); //contatenate to keymaterial
}
//showBytes("Final key material", keymaterial);
byte[] deskey = new byte[24];
Array.Copy(keymaterial, deskey, deskey.Length);
Array.Clear(psbytes, 0, psbytes.Length);
Array.Clear(data00, 0, data00.Length);
Array.Clear(result, 0, result.Length);
Array.Clear(hashtarget, 0, hashtarget.Length);
Array.Clear(keymaterial, 0, keymaterial.Length);
return deskey;
}
public static byte[] DecryptKey(byte[] cipherData, byte[] desKey, byte[] IV)
{
MemoryStream memst = new MemoryStream();
TripleDES alg = TripleDES.Create();
alg.Key = desKey;
alg.IV = IV;
try
{
CryptoStream cs = new CryptoStream(memst, alg.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(cipherData, 0, cipherData.Length);
cs.Close();
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
return null;
}
byte[] decryptedData = memst.ToArray();
return decryptedData;
}
private static SecureString GetSecPswd(String prompt)
{
SecureString password = new SecureString();
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write(prompt);
Console.ForegroundColor = ConsoleColor.Magenta;
while (true)
{
ConsoleKeyInfo cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.Enter)
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine();
return password;
}
else if (cki.Key == ConsoleKey.Backspace)
{
// remove the last asterisk from the screen...
if (password.Length > 0)
{
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.Write(" ");
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
password.RemoveAt(password.Length - 1);
}
}
else if (cki.Key == ConsoleKey.Escape)
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine();
return password;
}
else if (Char.IsLetterOrDigit(cki.KeyChar) || Char.IsSymbol(cki.KeyChar))
{
if (password.Length < 20)
{
password.AppendChar(cki.KeyChar);
Console.Write("*");
}
else
{
Console.Beep();
}
}
else
{
Console.Beep();
}
}
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02) //expect integer
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
count = binr.ReadByte(); // data size in next byte
else
if (bt == 0x82)
{
highbyte = binr.ReadByte(); // data size in next 2 bytes
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt; // we already have the data size
}
while (binr.ReadByte() == 0x00)
{ //remove high order zeros in data
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte
return count;
}
The problem is with this code:
RSAParameters rsap = new RSAParameters
{
Modulus = Encoding.ASCII.GetBytes(privateKey)
};
You are reading privateKey as a byte array encoded in a string. But your private key is not in that format, it is in PEM format. Check this answer: How to read a PEM RSA private key from .NET. for reading a PEM key in C#. Maybe you should decrypt the base64 in your pem string aswell.

Key not valid for use in specified state in RSA encryption

here is my code.get error in encryption method
encryptedData = RSA.Encrypt(Data, DoOAEPPadding);
The method throws "Key not valid for use in specified state."
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
private void button1_Click(object sender, EventArgs e)
{
var rsa = new RSACryptoServiceProvider();
var rsaKeyPair = DotNetUtilities.GetRsaKeyPair(rsa);
var writer = new StringWriter();
var writer2 = new StringWriter();
var pemWriter = new PemWriter(writer);
var pemWriter2 = new PemWriter(writer2);
pemWriter.WriteObject(rsaKeyPair.Public);
pemWriter2.WriteObject(rsaKeyPair.Private);
string Pub = writer.ToString();
string Prv = writer2.ToString();
plaintext = ByteConverter.GetBytes(txtplain.Text);
encryptedtext = Encryption(plaintext, Pub, false);
}
get error here when encrypt data using by RSA encryption method.here pass DATA as a byte and RSA public key as a string.after that convert it to RSAParanetrs "RSA.ImportParameters(GetRSAParameters(RSAKey));"
then encrypt data get this error.
static public byte[] Encryption(byte[] Data, string RSAKey, bool DoOAEPPadding)
{
try
{
byte[] encryptedData;
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
RSA.ImportParameters(GetRSAParameters(RSAKey));
encryptedData = RSA.Encrypt(Data, DoOAEPPadding); // get error "Key not valid for use in specified state"
}
return encryptedData;
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
return null;
}
}
private static RSAParameters GetRSAParameters(string pPublicKey)
{
byte[] lDer;
int lBeginStart = "-----BEGIN PUBLIC KEY-----".Length;
int lEndLenght = "-----END PUBLIC KEY-------".Length;
string KeyString = pPublicKey.Substring(lBeginStart, (pPublicKey.Length - lBeginStart - lEndLenght));
lDer = Convert.FromBase64String(KeyString);
RSAParameters lRSAKeyInfo = new RSAParameters();
lRSAKeyInfo.Modulus = GetModulus(lDer);
lRSAKeyInfo.Exponent = GetExponent(lDer);
return lRSAKeyInfo;
}
private static byte[] GetModulus(byte[] pDer)
{
string lModulus = BitConverter.ToString(pDer).Replace("-", "").Substring(58, 256);
return StringHexToByteArray(lModulus);
}
private static byte[] GetExponent(byte[] pDer)
{
int lExponentLenght = pDer[pDer.Length - 3];
string lExponent = BitConverter.ToString(pDer).Replace("-", "").Substring((pDer.Length * 2) - lExponentLenght * 2, lExponentLenght * 2);
return StringHexToByteArray(lExponent);
}
public static byte[] StringHexToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}

JWT decoding fails at the time of creating key

I have written the following to decode JWT token, with the help of stackoverflow of course. I think there seems to be an issue with the public key.
Because it fails only at the key creation.
class Program
{
static void Main(string[] args)
{
string token = "TOKEN STRING";
string key = "KEY STRING";
string result = ValidateJWT(token, key);
Console.WriteLine(result);
}
public static string ValidateJWT(string tokenTodecode, string publicKey)
{
string[] parts = tokenTodecode.Split('.');
string header = parts[0];
string payload = parts[1];
byte[] crypto = Base64UrlDecode(parts[2]);
string headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
JObject headerData = JObject.Parse(headerJson);
string payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));
JObject payloadData = JObject.Parse(payloadJson);
var keyBytes = Convert.FromBase64String(publicKey);
AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(keyBytes);
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)asymmetricKeyParameter;
RSAParameters rsaParameters = new RSAParameters();
rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParameters);
SHA256 sha256 = SHA256.Create();
byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(parts[0] + '.' + parts[1]));
RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
rsaDeformatter.SetHashAlgorithm("SHA256");
if (!rsaDeformatter.VerifySignature(hash, FromBase64Url(parts[2])))
{
return "";
}
return payloadData.ToString();
}
public static byte[] Base64UrlDecode(string arg)
{
var decrypted = ToBase64(arg);
return Convert.FromBase64String(decrypted);
}
public static string ToBase64(string arg)
{
if (arg == null)
{
throw new ArgumentNullException("arg");
}
var s = arg
.PadRight(arg.Length + (4 - arg.Length % 4) % 4, '=')
.Replace("_", "/")
.Replace("-", "+");
return s;
}
static byte[] FromBase64Url(string base64Url)
{
string padded = base64Url.Length % 4 == 0
? base64Url : base64Url + "====".Substring(base64Url.Length % 4);
string base64 = padded.Replace("_", "/")
.Replace("-", "+");
return Convert.FromBase64String(base64);
}
}
And the following is the error I get. Can someone please help me to fix this ?
Is that the case that the key is wrong ?

how to encrypt string in asp.net c# [duplicate]

This question already has answers here:
Encrypting & Decrypting a String in C# [duplicate]
(7 answers)
Closed 6 years ago.
public string EncryptPwd(String strString)
{
int intAscii;
string strEncryPwd = "";
for (int intIndex = 0; intIndex < strString.ToString().Length; intIndex++)
{
intAscii = (int)char.Parse(strString.ToString().Substring(intIndex, 1));
intAscii = intAscii + 5;
strEncryPwd += (char)intAscii;
}
return strEncryPwd;
}
This is my code.Please suggest me it is right way or not.
you can use this code:
Encrypt string with password:
public static string EncryptString(string Message, string Passphrase)
{
byte[] Results;
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
byte[] DataToEncrypt = UTF8.GetBytes(Message);
try
{
ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
}
finally
{
TDESAlgorithm.Clear();
HashProvider.Clear();
}
return Convert.ToBase64String(Results);
}
and Decrypt String with password:
public static string DecryptString(string Message, string Passphrase)
{
byte[] Results;
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
byte[] DataToDecrypt = Convert.FromBase64String(Message);
// Step 5. Bat dau giai ma chuoi
try
{
ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
}
catch (Exception) { Results = DataToDecrypt; }
finally
{
TDESAlgorithm.Clear();
HashProvider.Clear();
}
return UTF8.GetString(Results);
}
Do you have a way to decrypt that? Here is another answer on SO
private static readonly UTF8Encoding Encoder = new UTF8Encoding();
public static string Encrypt(string unencrypted)
{
if (string.IsNullOrEmpty(unencrypted))
return string.Empty;
try
{
var encryptedBytes = MachineKey.Protect(Encoder.GetBytes(unencrypted));
if (encryptedBytes != null && encryptedBytes.Length > 0)
return HttpServerUtility.UrlTokenEncode(encryptedBytes);
}
catch (Exception)
{
return string.Empty;
}
return string.Empty;
}
public static string Decrypt(string encrypted)
{
if (string.IsNullOrEmpty(encrypted))
return string.Empty;
try
{
var bytes = HttpServerUtility.UrlTokenDecode(encrypted);
if (bytes != null && bytes.Length > 0)
{
var decryptedBytes = MachineKey.Unprotect(bytes);
if(decryptedBytes != null && decryptedBytes.Length > 0)
return Encoder.GetString(decryptedBytes);
}
}
catch (Exception)
{
return string.Empty;
}
return string.Empty;
}
I agree with all the previous answers (especially share pvv) but in case you really did want a Caesar Cipher (Caesar Cipher is a very weak encryption and should not be used in production), and if this is a learning exercise, then here is some code
string strString = "abcdefghijklmnopqrstuvwxyz";
string enc = String.Join("", strString.ToArray().Select(x =>(char)( 'a' + (x-'a'+5)%26)));
Console.WriteLine(enc);
Or using a for loop like you did
string strEncryPwd = "";
for (int index = 0; index < strString.ToString().Length; index++)
{
int plainChar = strString[index];
int encrypted = 'a' + (plainChar - 'a' + 5) % 26;
strEncryPwd += (char)encrypted;
}
Console.WriteLine(strEncryPwd);

Categories