编辑:感谢LasseVågsætherKarlsen的建议。我能够解决我的问题。我使用Bitconverter将字节转换为字符串,然后使用UTF8.GetBytes将其转换回字节。这行不通。我决定使用
Convert.FromBase64String
Convert.ToBase64String
我正在尝试将RSA实施到客户端服务器C#程序中。
我的计划是在服务器上生成公用密钥,并在握手期间将其发送给客户端。然后,客户端将生成一个用RSA公钥加密的AES密钥,并将其发送回服务器。然后,我将在会话期间使用AES加密通信。
问题是,当服务器收到加密的消息时,出现错误消息,指出文件超出限制。即使将客户端上的加密消息和服务接收到的消息相同,如果将它们转换为XML字符串以比较2,它们的长度和内容也相同。
错误:System.Security.Cryptography.CryptographicException:要解密的数据超出了该模块的最大值256个字节。
将序列化的公钥发送给客户端:
RSAManager rSAManager = new RSAManager();
string publicKeyString = SerializeKey(rSAManager.publicKey); // Serialize the public key so we can send it to the clients
// Send test data to the remote device.
Send(client, $"{publicKeyString}!");
RSAManager
类:public class RSAManager
{
#region Keys, Containername, Keysizes
public RSAParameters publicKey;
public RSAParameters privateKey;
static string CONTAINER_NAME = "MyContainerName";
public enum KeySizes
{
SIZE_512 = 512,
SIZE_1024 = 1024,
SIZE_2048 = 2048,
SIZE_952 = 952,
SIZE_1369 = 1369
};
#endregion
#region Methods
public RSAManager()
{
GenerateKeys();
}
public void GenerateKeys()
{
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.PersistKeyInCsp = false; //Don't store the keys in a key container
publicKey = rsa.ExportParameters(false);
privateKey = rsa.ExportParameters(true);
}
}
/// <summary>
/// Encrypts the given byte array with the RSA standard
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public byte[] Encrypt(string message)
{
byte[] input = Encoding.UTF8.GetBytes(message);
byte[] encrypted;
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.PersistKeyInCsp = false;
rsa.ImportParameters(publicKey);
encrypted = rsa.Encrypt(input, true);
}
return encrypted;
}
/// <summary>
/// Decrypts the given byte array with the RSA standard
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string Decrypt(byte[] encrypted)
{
byte[] decrypted;
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.PersistKeyInCsp = false;
rsa.ImportParameters(privateKey);
decrypted = rsa.Decrypt(encrypted, true);
}
return Encoding.UTF8.GetString(decrypted);
}
static string SerializeKey(RSAParameters publicKey)
{
string publicKeyString;
{
//we need some buffer
var sw = new System.IO.StringWriter();
//we need a serializer
var xs1 = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters));
//serialize the key into the stream
xs1.Serialize(sw, publicKey);
//get the string from the stream
publicKeyString = sw.ToString();
}
return publicKeyString;
}
static RSAParameters DeSerializeKey(string publicKeyString)
{
var sr = new System.IO.StringReader(publicKeyString);
//we need a deserializer
var xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters));
//get the object back from the stream
return (RSAParameters)xs.Deserialize(sr);
}
string publicKeyString = TrimString(new string[] {"!"},content);
RSAManager rSAManager = new RSAManager();
rSAManager.publicKey = DeSerializeKey(publicKeyString);
string randomAESKey = GetRandomString(40);
Console.WriteLine($"Randomstring: {randomAESKey");
byte[] encrypted = rSAManager.Encrypt(randomAESKey);
string encryptedAESKey = BitConverter.ToString(encrypted);
Console.WriteLine($"Encrypted. {encryptedAESKey}");
Console.WriteLine("Length of encrypted string: " + encryptedAESKey.Length);
// Echo the data back to the server.
Send(handler, encryptedAESKey);
// Write the response to the console.
Console.WriteLine("Length of encrypted response: " + response.Length);
Console.WriteLine("Length of public Key: " + SerializeKey(rSAManager.publicKey).Length);
// Decrypt functions needs byte array so we need to encode it. This line always causes the error.
string encryptedResponse = rSAManager.Decrypt(Encoding.UTF8.GetBytes(response));
// Received encrypted response
Console.WriteLine($"Decrypted response: {encryptedResponse}");
答案 0 :(得分:1)
为什么从加密字节取回字符串时使用BitConverter的任何原因? 您是否尝试使用Encoding.UTF8.GetString?
答案 1 :(得分:0)
可以使用RSA加密的数据的最大大小为245,您应该做的是使用随机生成的对称密钥对主块进行加密,然后使用私钥对该密钥进行加密。
This link on StackExchange提供了更多信息。
答案 2 :(得分:-1)
我强烈建议您考虑使用libsodium来解决此类问题。他们的明确目标是为密码操作提供更好的API,以减少滥用滥用库的可能性。
此外,您是否还考虑过如何认证服务器?您可能不需要新生成的RSA密钥。