我沒有安全背景,並且我已經處理的最多密碼術是使用從網上拾取的片段。經過一番閱讀後,很明顯我需要更好地理解這些算法的工作原理。所以請忍受任何天真。使用有效值初始化SymmetricAlgorithm
我試圖實現一些普通/抽象的方法,期望完全初始化SymmetricAlgorithm
實例。據我所見,轉換方法可以很好地執行,而調用代碼則沒有。我得到的例外情況如下等等:
The input data is not a complete block.
Length of the data to decrypt is invalid.
用法:
using System;
using System.Security.Cryptography;
using System.Text;
public class Program
{
private static void Main (string [] args)
{
var cycled = "";
Exception exception = null;
var output = new byte [] { };
var encoding = Encoding.UTF8;
var source = "Dude, where's my car?!";
var algorithm = RijndaelManaged.Create();
algorithm.GenerateIV();
algorithm.GenerateKey();
algorithm.Mode = CipherMode.CBC; // CipherMode.OFB;
// I've tried multiple combinations of algorithms and modes, which all result in exceptions.
if (SecurityUtilities.Encrypt(source, encoding, algorithm, out output, out exception))
{
if (SecurityUtilities.Decrypt(output, encoding, algorithm, out cycled, out exception))
{
var r = cycled == source;
Console.Write("{0} = {1} == {2}.", r, source, cycled);
}
else
{
Console.Write(exception);
}
}
else
{
Console.Write(exception);
}
Console.ReadKey();
}
}
通用代碼:
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
public static class SecurityUtilities
{
public static bool Encrypt (string source, Encoding encoding, SymmetricAlgorithm algorithm, out string output, out Exception exception)
{
var result = false;
output = "";
exception = null;
if (source == null) { throw (new ArgumentNullException("source")); }
if (encoding == null) { throw (new ArgumentNullException("encoding")); }
if (algorithm == null) { throw (new ArgumentNullException("algorithm")); }
try
{
var bytesEncrypted = new byte [] { };
var bytesSource = encoding.GetBytes(source);
if (SecurityUtilities.Encrypt(bytesSource, algorithm, out bytesEncrypted, out exception))
{
output = encoding.GetString(bytesEncrypted);
result = true;
}
}
catch (Exception e)
{
exception = e;
}
return (result);
}
public static bool Encrypt (string source, Encoding encoding, SymmetricAlgorithm algorithm, out byte [] output, out Exception exception)
{
var result = false;
output = null;
exception = null;
if (source == null) { throw (new ArgumentNullException("source")); }
if (encoding == null) { throw (new ArgumentNullException("encoding")); }
if (algorithm == null) { throw (new ArgumentNullException("algorithm")); }
try
{
var bytesEncrypted = new byte [] { };
var bytesSource = encoding.GetBytes(source);
if (SecurityUtilities.Encrypt(bytesSource, algorithm, out bytesEncrypted, out exception))
{
output = bytesEncrypted;
result = true;
}
}
catch (Exception e)
{
exception = e;
}
return (result);
}
public static bool Encrypt (byte [] source, SymmetricAlgorithm algorithm, out byte [] output, out Exception exception)
{
var result = false;
output = null;
exception = null;
if (source == null) { throw (new ArgumentNullException("source")); }
if (algorithm == null) { throw (new ArgumentNullException("algorithm")); }
try
{
using (var memoryStream = new MemoryStream())
{
using (var transform = algorithm.CreateEncryptor())
{
using (var cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
{
cryptoStream.Write(source, 0, source.Length);
}
}
output = memoryStream.ToArray();
}
result = true;
}
catch (Exception e)
{
exception = e;
}
return (result);
}
public static bool Decrypt (string source, Encoding encoding, SymmetricAlgorithm algorithm, out string output, out Exception exception)
{
var result = false;
output = "";
exception = null;
if (source == null) { throw (new ArgumentNullException("source")); }
if (encoding == null) { throw (new ArgumentNullException("encoding")); }
if (algorithm == null) { throw (new ArgumentNullException("algorithm")); }
try
{
var bytesDecrypted = new byte [] { };
var bytesSource = encoding.GetBytes(source);
if (SecurityUtilities.Decrypt(bytesSource, algorithm, out bytesDecrypted, out exception))
{
output = encoding.GetString(bytesDecrypted);
result = true;
}
}
catch (Exception e)
{
exception = e;
}
return (result);
}
public static bool Decrypt (byte [] source, Encoding encoding, SymmetricAlgorithm algorithm, out string output, out Exception exception)
{
var result = false;
output = "";
exception = null;
if (source == null) { throw (new ArgumentNullException("source")); }
if (encoding == null) { throw (new ArgumentNullException("encoding")); }
if (algorithm == null) { throw (new ArgumentNullException("algorithm")); }
try
{
var bytesSource = source;
var bytesDecrypted = new byte [] { };
if (SecurityUtilities.Decrypt(bytesSource, algorithm, out bytesDecrypted, out exception))
{
output = encoding.GetString(bytesDecrypted);
result = true;
}
}
catch (Exception e)
{
exception = e;
}
return (result);
}
public static bool Decrypt (byte [] source, SymmetricAlgorithm algorithm, out byte [] output, out Exception exception)
{
var result = false;
output = null;
exception = null;
if (source == null) { throw (new ArgumentNullException("source")); }
if (algorithm == null) { throw (new ArgumentNullException("algorithm")); }
try
{
using (var memoryStream = new MemoryStream(source))
{
using (var transform = algorithm.CreateDecryptor())
{
using (var cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read))
{
cryptoStream.Read(source, 0, source.Length);
}
}
output = memoryStream.ToArray();
}
result = true;
}
catch (Exception e)
{
exception = e;
}
return (result);
}
}
核心問題是的,在Encrypt/Decrypt
方法中是否存在錯誤?如果不存在,調用代碼中需要的最低限度更改才能使其正常工作?
你的異常處理是有問題的。讓他們冒泡而不是將它們作爲價值回報。這種模式對密碼學來說尤其危險,但一般來說不好。 – usr
@usr:'TryXXX(out exp)'模式是庫的其餘部分使用的,所以我無法控制它。但是你爲什麼說這對冷印術來說特別不好? –
因爲調用者可以無意中忽略返回值並繼續執行無效數據。如果安全決策依賴於(可能使用加密代碼),那可能是災難性的。 – usr