【发布时间】:2018-11-08 09:42:27
【问题描述】:
编辑:感谢 Lasse Vågsæther Karlsen 的建议。我能够解决我的问题。我使用 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);
服务器接收和解密 AES KEY
// 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}");
【问题讨论】:
-
BitConverter.ToString和Encoding.GetBytes不能成对使用。
标签: c# encryption aes rsa