我试着处理一些数据的加密/解密。让它和缓冲区一起工作对我来说是一项艰苦的工作。
这是我想出的代码:
public static string Encrypt(string dataToEncrypt, byte[] publicKeyInfo)
{
//// Our bytearray to hold all of our data after the encryption
byte[] encryptedBytes = new byte[0];
using (var rsa = new RSACryptoServiceProvider())
{
try
{
var encoder = new UTF8Encoding();
byte[] encryptThis = encoder.GetBytes(dataToEncrypt);
//// Importing the public key
rsa.ImportCspBlob(publicKeyInfo);
int blockSize = (rsa.KeySize / 8) - 32;
//// buffer to write byte sequence of the given block_size
byte[] buffer = new byte[blockSize];
byte[] encryptedBuffer = new byte[blockSize];
//// Initializing our encryptedBytes array to a suitable size, depending on the size of data to be encrypted
encryptedBytes = new byte[encryptThis.Length + blockSize - (encryptThis.Length % blockSize) + 32];
for (int i = 0; i < encryptThis.Length; i += blockSize)
{
//// If there is extra info to be parsed, but not enough to fill out a complete bytearray, fit array for last bit of data
if (2 * i > encryptThis.Length && ((encryptThis.Length - i) % blockSize != 0))
{
buffer = new byte[encryptThis.Length - i];
blockSize = encryptThis.Length - i;
}
//// If the amount of bytes we need to decrypt isn't enough to fill out a block, only decrypt part of it
if (encryptThis.Length < blockSize)
{
buffer = new byte[encryptThis.Length];
blockSize = encryptThis.Length;
}
//// encrypt the specified size of data, then add to final array.
Buffer.BlockCopy(encryptThis, i, buffer, 0, blockSize);
encryptedBuffer = rsa.Encrypt(buffer, false);
encryptedBuffer.CopyTo(encryptedBytes, i);
}
}
catch (CryptographicException e)
{
Console.Write(e);
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
//// Convert the byteArray using Base64 and returns as an encrypted string
return Convert.ToBase64String(encryptedBytes);
}
public static string Decrypt(string dataToDecrypt, byte[] privateKeyInfo)
{
//// The bytearray to hold all of our data after decryption
byte[] decryptedBytes;
//Create a new instance of RSACryptoServiceProvider.
using (var rsa = new RSACryptoServiceProvider())
{
try
{
byte[] bytesToDecrypt = Convert.FromBase64String(dataToDecrypt);
//// Import the private key info
rsa.ImportCspBlob(privateKeyInfo);
//// No need to subtract padding size when decrypting
int blockSize = rsa.KeySize / 8;
//// buffer to write byte sequence of the given block_size
byte[] buffer = new byte[blockSize];
//// buffer containing decrypted information
byte[] decryptedBuffer = new byte[blockSize];
//// Initializes our array to make sure it can hold at least the amount needed to decrypt.
decryptedBytes = new byte[dataToDecrypt.Length];
for (int i = 0; i < bytesToDecrypt.Length; i += blockSize)
{
if (2 * i > bytesToDecrypt.Length && ((bytesToDecrypt.Length - i) % blockSize != 0))
{
buffer = new byte[bytesToDecrypt.Length - i];
blockSize = bytesToDecrypt.Length - i;
}
//// If the amount of bytes we need to decrypt isn't enough to fill out a block, only decrypt part of it
if (bytesToDecrypt.Length < blockSize)
{
buffer = new byte[bytesToDecrypt.Length];
blockSize = bytesToDecrypt.Length;
}
Buffer.BlockCopy(bytesToDecrypt, i, buffer, 0, blockSize);
decryptedBuffer = rsa.Decrypt(buffer, false);
decryptedBuffer.CopyTo(decryptedBytes, i);
}
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
//// We encode each byte with UTF8 and then write to a string while trimming off the extra empty data created by the overhead.
var encoder = new UTF8Encoding();
return encoder.GetString(decryptedBytes).TrimEnd(new[] { '\0' });
}我试着看看我是否能把它分开,但在我的努力下,我想出了一个我认为更复杂的方法(更高的圈复杂度)。我突然有很多if语句,必须处理加密模式,但也需要处理来自UTF8或BASE64的编码。
发布于 2011-12-10 10:44:46
我对密码学方面没有任何评论,但我有几个一般的编程要点:
encryptedBytes数组初始化为空数组,因为您稍后会重新初始化它。System.Text.Encoding.UTF8而不是手动实例化UTF8Encoding。encryptedBytes数组时的第24行和检查“要解析的额外信息”的第29行),可能值得在条件和数组构建中拆分内联计算。catch子句时结束代码执行,因为如果程序失败,您不希望程序继续执行该算法。此外,我建议将try子句中的代码再分解一些,这样您就只能在可能导致CryptographicException的确切行周围设置try-catch块。这并不重要,但它可以帮助另一位读者很容易地识别出可能出现问题的台词(S)。除了上述要点之外,代码本身看起来结构也相当好,而且符合逻辑。
发布于 2011-12-09 21:28:31
在欧洲央行模式下,你使用RSA作为分组密码。它通常不是这样使用的。除非您有很好的理由这样做,否则您应该只进行一个RSA加密,一个分组密码的安全随机密钥(即AES),然后使用该密钥对您的消息进行加密。
由于您正在将string转换为string,很明显,内存和延迟都不是问题,所以您可以通过使用MemoryStream和CryptoStream来避免与byte[]s打交道。您还可以使用Encoding.UTF8稍微简化en/解码步骤。
https://codereview.stackexchange.com/questions/6662
复制相似问题