如何在C#中使用RSA 2048算法解密加密字符串? [英] How to decrypt an encrypted string using RSA 2048 algorithm in C#?
问题描述
我想使用RSA 2048算法解密加密的字符串。我能够成功加密相同的。但是在解密时我得到如下例外:
输入不是有效的Base-64字符串,因为它包含一个非基数为64的字符,两个以上的填充字符,或填充字符中的非法字符。
我的尝试:
RSA加密:
#region Encrypt_AES_With_CBPublicKey
public string Encrypt_AES_With_CBPublicKey(CBAPIDetails objReqAPI)// string Request_AES_string,string RSAPrivateKey
{
try
{
txtLog.Text + =客户端:使用CB公钥加密AES密钥开始于:+ MethodInfo.GetCurrentMethod()。Name + Environment.NewLine;
/ * Bouncy Castle * /
// var keyBytes =
//Convert.FromBase64String(objReqAPI.AES_KEY); //你的钥匙在这里Deept
//// var keyBytes =
////Convert.FromBase64String(test1); //你的密钥在这里Deept
// var eng = new Pkcs1Encoding(new RsaEngine());
//使用(var reader = File.OpenText(NeSTCommonClass.CB_Public_KeyFile))//包含RSA PKCS1私钥的文件
// {
// var keyParameter =(AsymmetricKeyParameter)new PemReader(读取器).ReadObject();
// eng.Init(true,keyParameter);
//}
// var encrypted = Convert.ToBase64String(eng.ProcessBlock(keyBytes,0,keyBytes.Length));
//返回加密;
/ * Bouncy Castle * /
/ *没有Bouncy Castle在这里工作* /
var publicKey =< RSAKeyValue>< Modulus> ; 21wEnTU + mcD2w0Lfo1Gv4rtcSWsQJQTNa6gio05AOkV / Er9w3Y13Ddo5wGtjJ19402S71HUeN0vbKILLJdRSES5MHSdJPSVrOqdrll / vLXxDxWs / U0UT1c8u6k / Ogx9hTtZxYwoeYqdhDblof3E75d9n2F0Zvf6iTb4cI7j6fMs = LT; /模量><指数> AQAB< /指数>< / RSAKeyValue>中;
// var publicKey =模数(Common.ReadTextFile(Common.CB_Public_KeyFile));
var AESkeyBytes = Encoding.UTF8.GetBytes(objReqAPI.AES_KEY);
使用(var rsa = new RSACryptoServiceProvider(2048))
{
try
{
//客户端使用服务器$发出的公钥加密数据b $ b rsa.FromXmlString(publicKey.ToString());
var encryptedData = rsa.Encrypt(AESkeyBytes,true);
var base64Encrypted = Convert.ToBase64String(encryptedData);
txtLog.Text + =客户端:使用CB公钥加密AES密钥完成于:+ MethodInfo.GetCurrentMethod()。Name + Environment.NewLine;
返回base64Encrypted;
}
最后
{
rsa.PersistKeyInCsp = false;
}
}
}
catch(exception ex)
{
//NeSTCommonClass.WriteTextFile(LogPath + Logfilename,Encryption with RSA私钥失败:+ ex.Message.ToString()+,true);
抛出前;
}
}
#region模数
公共静态字符串模数(string pem)
{
byte [] x509der = null;
x509der = Convert.FromBase64String(pem.Replace(----- BEGIN PUBLIC KEY -----,).Replace(----- END PUBLIC KEY- ----,));
byte [] seqOID = {0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01};
MemoryStream ms = new MemoryStream(x509der);
BinaryReader reader = new BinaryReader(ms);
if(reader.ReadByte()== 0x30)ReadASNLength(reader); //跳过大小
else返回null;
int identifierSize = 0; //对象标识符部分的总长度
if(reader.ReadByte()== 0x30)identifierSize = ReadASNLength(reader);
else返回null;
if(reader.ReadByte()== 0x06)//是对象标识符的下一个元素吗?
{
int oidLength = ReadASNLength(读者);
byte [] oidBytes = new byte [oidLength];
reader.Read(oidBytes,0,oidBytes.Length);
if(oidBytes.SequenceEqual(seqOID)== false)返回null; //是对象标识符rsaEncryption PKCS#1?
int remainingBytes = identifierSize - 2 - oidBytes.Length;
reader.ReadBytes(remainingBytes);
}
if(reader.ReadByte()== 0x03)//是下一个元素是一个字符串吗?
{
ReadASNLength(读者); //跳过
reader.ReadByte(); //跳过未使用的位指示符
if(reader.ReadByte()== 0x30)
{
ReadASNLength(reader); //跳过大小
if(reader.ReadByte()== 0x02)//是整数吗?
{
int modulusSize = ReadASNLength(读者);
byte [] modulus = new byte [modulusSize];
reader.Read(modulus,0,modulus.Length);
if(modulus [0] == 0x00)//剥离第一个字节,如果它是0
{
byte [] tempModulus = new byte [modulus.Length - 1];
Array.Copy(模数,1,tempModulus,0,modulus.Length - 1);
modulus = tempModulus;
}
if(reader.ReadByte()== 0x02)//是整数吗?
{
int exponentSize = ReadASNLength(读者);
byte [] exponent = new byte [exponentSize];
reader.Read(exponent,0,exponent.Length);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters RSAKeyInfo = new RSAParameters();
RSAKeyInfo.Modulus =模数;
RSAKeyInfo.Exponent = exponent;
rsa.ImportParameters(RSAKeyInfo);
//返回rsa.ToXmlString(false).Replace(< RSAKeyValue>< Modulus>,)。Replace(< / Modulus>< Exponent> AQAB< / Exponent>< / RSAKeyValue>,);
返回rsa.ToXmlString(false);
}
}
}
}
返回null;
}
#endregion
#region ReadASNLength
public static int ReadASNLength(BinaryReader reader)
{//注意:仅此方法读取长度最多4个字节,因为这对大多数情况来说是令人满意的。
int length = reader.ReadByte();
if((length& 0x00000080)== 0x00000080)//长度大于1字节
{
int count = length& 0x0000000f;
byte [] lengthBytes = new byte [4];
reader.Read(lengthBytes,4 - count,count);
Array.Reverse(lengthBytes); //
length = BitConverter.ToInt32(lengthBytes,0);
}
返回长度;
}
#endregion
#endregion
RSA解密:
#region AES_Decrypt_CB_Private_Key
public string AES_Decrypt_CB_Private_Key(CBAPIDetails objReqAPI)
{
try
{
/ * Bouncy Castle * /
// string CBPvtKeyString = Common.ReadTextFile(Common.CB_Private_KeyFile);
// CBPvtKeyString = CBPvtKeyString.Replace(----- BEGIN RSA PRIVATE KEY -----,).Replace(----- END RSA PRIVATE KEY ----- ,);
// var keyBytes =
// Convert.FromBase64String(Common.CB_PrivateKey); //你的密钥在这里
// RsaPrivateCrtKeyParameters privateKey =(RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(keyBytes);
// IAsymmetricBlockCipher eng = new Org.BouncyCastle.Crypto.Encodings.Pkcs1Encoding(new Org.BouncyCastle.Crypto.Engines.RsaEngine());
//eng.Init(false,privyKey);
// var base64Encrypted = objReqAPI.encrypyedRequestKeyData;
// byte [] encdata = System.Convert.FromBase64String(objReqAPI.encrypyedRequestKeyData);
//字符串结果= System.Convert.ToBase64String(eng.ProcessBlock(encdata,0,encdata.Length));
//返回结果;
/ * Bouncy Castle * /
/ *没有Bouncy Castle在这里工作* /
// var privateKey =< RSAKeyValue>< Modulus> 21wEnTU + mcD2w0Lfo1Gv4rtcSWsQJQTNa6gio05AOkV / Er9w3Y13Ddo5wGtjJ19402S71HUeN0vbKILLJdRSES5MHSdJPSVrOqdrll / vLXxDxWs / U0UT1c8u6k / Ogx9hTtZxYwoeYqdhDblof3E75d9n2F0Zvf6iTb4cI7j6fMs = LT; /模量><指数> AQAB< /指数>< P> / aULPE6jd5IkwtWXmReyMUhmI / nfwfkQSyl7tsg2PKdpcxk4mpPZUdEQhHQLvE84w2DhTyYkPHCtq / mMKE3MHw ==< / P>< Q> 3WV46X9Arg2l9cxb67KVlNVXyCqc / W + LWT / tbhLJvV2xCF / 0rWKPsBJ9MC6cquaqNPxWWEav8RAVbmmGrJt51Q ==< / Q>< DP> 8TuZFgBMpBoQcGUoS2goB4st6aVq1FcG0hVgHhUI0GMAfYFNPmbDV3cY2IBt8Oj / uYJYhyhlaj5YTqmGTYbATQ ==< / DP>< DQ> FIoVbZQgrAUYIHWVEYi / 187zFd7eMct / Yi7kGBImJStMATrluDAspGkStCWe4zwDDmdam1XzfKnBUzz3AYxrAQ ==< / DQ>< InverseQ> QPU3Tmt8nznSgYZ + 5jUo9E0SfjiTu435ihANiHqqjasaUNvOHKumqzuBZ8NRtkUhS6dsOEb8A2ODvy7KswUxyA = =< / InverseQ>< d取代; cgoRoAUpSVfHMdYXW9nA3dfX75dIamZn wPtFHq80ttagbIe4ToYYCcyUz5NElhiNQSESgS5uCgNWqWXt5PnPu4XmCXx6utco1UVH8HGLahzbAnSy6Cj3iUIQ7Gj + 9gQ7PkC434HTtHazmxVgIR5l56ZjoQ8yGNCPZnsdYEmhJWk = LT; / d取代;< / RSAKeyValue>中;
string CB_Private_Key = Common.ReadTextFile(Common.CB_Private_KeyFile);
var privateKey =模数(CB_Private_Key);
var testData = Encoding.UTF8.GetBytes(objReqAPI.encrypyedRequestKeyData);
使用(var rsa = new RSACryptoServiceProvider(2048))
{
try
{
var base64Encrypted = objReqAPI.encrypyedRequestKeyData;
//服务器使用私钥解密数据
rsa.FromXmlString(privateKey);
var resultBytes = Convert.FromBase64String(base64Encrypted);
var decryptedBytes = rsa.Decrypt(resultBytes,true);
var decryptedData = Encoding.UTF8.GetString(decryptedBytes);
返回decryptedData.ToString();
}
最后
{
rsa.PersistKeyInCsp = false;
}
}
/ *没有Bouncy Castle在这里工作* /
}
catch(exception ex)
{
throw ex;
}
}
#endregion
阅读错误信息,非常清楚:
Quote:input不是有效的Base-64字符串,因为它包含非基本64字符,两个以上的填充字符或填充字符中的非法字符。
这意味着什么 - 你试图从Base64转换的字符串不是有效的Base64字符串。
因此,请使用调试器,并准确查看字符串中的内容及其来源。
我们无法为您执行此操作 - 我们无法访问您的数据...
I want to decrypt an encrypted string using RSA 2048 Algorithm. I am able to encrypt the same successfully. But while decrypting I am getting the exception as below:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
What I have tried:
RSA Encryption:
#region Encrypt_AES_With_CBPublicKey public string Encrypt_AES_With_CBPublicKey(CBAPIDetails objReqAPI)//string Request_AES_string,string RSAPrivateKey { try { txtLog.Text += "Client:Encryption of AES Key with CB Public Key started under : " + MethodInfo.GetCurrentMethod().Name + Environment.NewLine; /* Bouncy Castle */ //var keyBytes = //Convert.FromBase64String(objReqAPI.AES_KEY); // your key here Deept ////var keyBytes = ////Convert.FromBase64String("test1"); // your key here Deept //var eng = new Pkcs1Encoding(new RsaEngine()); //using (var reader = File.OpenText(NeSTCommonClass.CB_Public_KeyFile)) // file containing RSA PKCS1 private key //{ // var keyParameter = (AsymmetricKeyParameter)new PemReader(reader).ReadObject(); // eng.Init(true, keyParameter); //} //var encrypted = Convert.ToBase64String(eng.ProcessBlock(keyBytes, 0, keyBytes.Length)); //return encrypted; /* Bouncy Castle */ /* Without Bouncy Castle Working here */ var publicKey = "<RSAKeyValue><Modulus>21wEnTU+mcD2w0Lfo1Gv4rtcSWsQJQTNa6gio05AOkV/Er9w3Y13Ddo5wGtjJ19402S71HUeN0vbKILLJdRSES5MHSdJPSVrOqdrll/vLXxDxWs/U0UT1c8u6k/Ogx9hTtZxYwoeYqdhDblof3E75d9n2F0Zvf6iTb4cI7j6fMs=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"; //var publicKey = Modulus(Common.ReadTextFile(Common.CB_Public_KeyFile)); var AESkeyBytes = Encoding.UTF8.GetBytes(objReqAPI.AES_KEY); using (var rsa = new RSACryptoServiceProvider(2048)) { try { // client encrypting data with public key issued by server rsa.FromXmlString(publicKey.ToString()); var encryptedData = rsa.Encrypt(AESkeyBytes, true); var base64Encrypted = Convert.ToBase64String(encryptedData); txtLog.Text += "Client:Encryption of AES Key with CB Public Key Finished under : " + MethodInfo.GetCurrentMethod().Name + Environment.NewLine; return base64Encrypted; } finally { rsa.PersistKeyInCsp = false; } } } catch (Exception ex) { //NeSTCommonClass.WriteTextFile(LogPath + Logfilename, "Encryption with RSA Private Key Failed:" + ex.Message.ToString() + "", true); throw ex; } } #region Modulus public static string Modulus(string pem) { byte[] x509der = null; x509der = Convert.FromBase64String(pem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "")); byte[] seqOID = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }; MemoryStream ms = new MemoryStream(x509der); BinaryReader reader = new BinaryReader(ms); if (reader.ReadByte() == 0x30) ReadASNLength(reader); //skip the size else return null; int identifierSize = 0; //total length of Object Identifier section if (reader.ReadByte() == 0x30) identifierSize = ReadASNLength(reader); else return null; if (reader.ReadByte() == 0x06) //is the next element an object identifier? { int oidLength = ReadASNLength(reader); byte[] oidBytes = new byte[oidLength]; reader.Read(oidBytes, 0, oidBytes.Length); if (oidBytes.SequenceEqual(seqOID) == false) return null; //is the object identifier rsaEncryption PKCS#1? int remainingBytes = identifierSize - 2 - oidBytes.Length; reader.ReadBytes(remainingBytes); } if (reader.ReadByte() == 0x03) //is the next element a bit string? { ReadASNLength(reader); //skip the size reader.ReadByte(); //skip unused bits indicator if (reader.ReadByte() == 0x30) { ReadASNLength(reader); //skip the size if (reader.ReadByte() == 0x02) //is it an integer? { int modulusSize = ReadASNLength(reader); byte[] modulus = new byte[modulusSize]; reader.Read(modulus, 0, modulus.Length); if (modulus[0] == 0x00) //strip off the first byte if it's 0 { byte[] tempModulus = new byte[modulus.Length - 1]; Array.Copy(modulus, 1, tempModulus, 0, modulus.Length - 1); modulus = tempModulus; } if (reader.ReadByte() == 0x02) //is it an integer? { int exponentSize = ReadASNLength(reader); byte[] exponent = new byte[exponentSize]; reader.Read(exponent, 0, exponent.Length); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); RSAParameters RSAKeyInfo = new RSAParameters(); RSAKeyInfo.Modulus = modulus; RSAKeyInfo.Exponent = exponent; rsa.ImportParameters(RSAKeyInfo); // return rsa.ToXmlString(false).Replace("<RSAKeyValue><Modulus>", "").Replace("</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>", ""); return rsa.ToXmlString(false); } } } } return null; } #endregion #region ReadASNLength public static int ReadASNLength(BinaryReader reader) {//Note: this method only reads lengths up to 4 bytes long as this is satisfactory for the majority of situations. int length = reader.ReadByte(); if ((length & 0x00000080) == 0x00000080) //is the length greater than 1 byte { int count = length & 0x0000000f; byte[] lengthBytes = new byte[4]; reader.Read(lengthBytes, 4 - count, count); Array.Reverse(lengthBytes); // length = BitConverter.ToInt32(lengthBytes, 0); } return length; } #endregion #endregion
RSA Decryption:
#region AES_Decrypt_CB_Private_Key public string AES_Decrypt_CB_Private_Key(CBAPIDetails objReqAPI) { try { /* Bouncy Castle */ //string CBPvtKeyString=Common.ReadTextFile(Common.CB_Private_KeyFile); //CBPvtKeyString = CBPvtKeyString.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", ""); //var keyBytes = // Convert.FromBase64String(Common.CB_PrivateKey); // your key here //RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(keyBytes); //IAsymmetricBlockCipher eng = new Org.BouncyCastle.Crypto.Encodings.Pkcs1Encoding(new Org.BouncyCastle.Crypto.Engines.RsaEngine()); //eng.Init(false, privateKey); //var base64Encrypted = objReqAPI.encrypyedRequestKeyData; //byte[] encdata = System.Convert.FromBase64String(objReqAPI.encrypyedRequestKeyData); //string result = System.Convert.ToBase64String(eng.ProcessBlock(encdata, 0, encdata.Length)); //return result; /* Bouncy Castle */ /* Without Bouncy Castle Working here */ //var privateKey = "<RSAKeyValue><Modulus>21wEnTU+mcD2w0Lfo1Gv4rtcSWsQJQTNa6gio05AOkV/Er9w3Y13Ddo5wGtjJ19402S71HUeN0vbKILLJdRSES5MHSdJPSVrOqdrll/vLXxDxWs/U0UT1c8u6k/Ogx9hTtZxYwoeYqdhDblof3E75d9n2F0Zvf6iTb4cI7j6fMs=</Modulus><Exponent>AQAB</Exponent><P>/aULPE6jd5IkwtWXmReyMUhmI/nfwfkQSyl7tsg2PKdpcxk4mpPZUdEQhHQLvE84w2DhTyYkPHCtq/mMKE3MHw==</P><Q>3WV46X9Arg2l9cxb67KVlNVXyCqc/w+LWt/tbhLJvV2xCF/0rWKPsBJ9MC6cquaqNPxWWEav8RAVbmmGrJt51Q==</Q><DP>8TuZFgBMpBoQcGUoS2goB4st6aVq1FcG0hVgHhUI0GMAfYFNPmbDV3cY2IBt8Oj/uYJYhyhlaj5YTqmGTYbATQ==</DP><DQ>FIoVbZQgrAUYIHWVEYi/187zFd7eMct/Yi7kGBImJStMATrluDAspGkStCWe4zwDDmdam1XzfKnBUzz3AYxrAQ==</DQ><InverseQ>QPU3Tmt8nznSgYZ+5jUo9E0SfjiTu435ihANiHqqjasaUNvOHKumqzuBZ8NRtkUhS6dsOEb8A2ODvy7KswUxyA==</InverseQ><D>cgoRoAUpSVfHMdYXW9nA3dfX75dIamZnwPtFHq80ttagbIe4ToYYCcyUz5NElhiNQSESgS5uCgNWqWXt5PnPu4XmCXx6utco1UVH8HGLahzbAnSy6Cj3iUIQ7Gj+9gQ7PkC434HTtHazmxVgIR5l56ZjoQ8yGNCPZnsdYEmhJWk=</D></RSAKeyValue>"; string CB_Private_Key = Common.ReadTextFile(Common.CB_Private_KeyFile); var privateKey = Modulus(CB_Private_Key); var testData = Encoding.UTF8.GetBytes(objReqAPI.encrypyedRequestKeyData); using (var rsa = new RSACryptoServiceProvider(2048)) { try { var base64Encrypted = objReqAPI.encrypyedRequestKeyData; // server decrypting data with private key rsa.FromXmlString(privateKey); var resultBytes = Convert.FromBase64String(base64Encrypted); var decryptedBytes = rsa.Decrypt(resultBytes, true); var decryptedData = Encoding.UTF8.GetString(decryptedBytes); return decryptedData.ToString(); } finally { rsa.PersistKeyInCsp = false; } } /* Without Bouncy Castle Working here */ } catch (Exception ex) { throw ex; } } #endregion
Read the error message, it's pretty clear:
Quote:The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
That means exactly what is says - the string you are trying to convert from Base64 is not a valid Base64 string.
So use the debugger, and look at exactly what you have in your string, and where it came from.
We can't do that for you - we have no access to your data...
这篇关于如何在C#中使用RSA 2048算法解密加密字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!