Nie*_*est 5 .net c# encryption rijndaelmanaged xamarin.ios
我正在使用以下(修剪)类来加密某些数据,然后再将其从iPad应用程序发送到WCF Web服务.
public class FlawedAlgorithm
{
protected static byte[] key = { 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
protected static byte[] vector = { 13, 37, 13, 37, 13, 37, 13, 37, 13, 37, 13, 37, 13, 37, 13, 37 };
protected ICryptoTransform encryptor, decryptor;
protected UTF8Encoding encoder;
public FlawedAlgorithm()
{
using (var rijndael = new RijndaelManaged())
{
this.encryptor = rijndael.CreateEncryptor(key, vector);
this.decryptor = rijndael.CreateDecryptor(key, vector);
}
this.encoder = new UTF8Encoding();
}
public string Encrypt(string unencrypted)
{
var buffer = this.encoder.GetBytes(unencrypted);
return Convert.ToBase64String(Encrypt(buffer));
}
public string Decrypt(string encrypted)
{
var buffer = Convert.FromBase64String(encrypted);
return this.encoder.GetString(Decrypt(buffer));
}
private byte[] Encrypt(byte[] buffer)
{
var encryptStream = new MemoryStream();
using (var cryptoStream = new CryptoStream(encryptStream, this.encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(buffer, 0, buffer.Length);
}
return encryptStream.ToArray();
}
private byte[] Decrypt(byte[] buffer)
{
var decryptStream = new MemoryStream();
using (var cryptoStream = new CryptoStream(decryptStream, this.decryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(buffer, 0, buffer.Length);
}
return decryptStream.ToArray();
}
}
Run Code Online (Sandbox Code Playgroud)
当我在服务器和iPad上运行以下代码时,两者都打印相同的加密字符串.
var algorithm = new FlawedAlgorithm();
Console.WriteLine(algorithm.Encrypt("Some string"));
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试加密第二个值时,服务器和iPad上的结果会有所不同.
var algorithm = new FlawedAlgorithm();
// The first encryption still functions correctly.
Console.WriteLine(algorithm.Encrypt("Some string"));
// This second encryption produces a different value on the iPad.
Console.WriteLine(algorithm.Encrypt("This text is a bit longer"));
Run Code Online (Sandbox Code Playgroud)
当我解密服务器上偏离的iPad结果时,部分解密的字符串是乱码.来自服务器的加密结果正确解密.
如果我FlawedAlgorithm为每个调用创建一个新实例,问题就不会表现出来,例如:
// These statements produce the correct results on the iPad.
Console.WriteLine(new FlawedAlgorithm().Encrypt("Some string"));
Console.WriteLine(new FlawedAlgorithm().Encrypt("This text is a bit longer"));
Run Code Online (Sandbox Code Playgroud)
这使我认为问题存在于所涉及对象的状态中.我检查了方法中的buffer变量,Encrypt(string)并且UTF8Encoding实例生成的值是正确的.这意味着该encryptor领域(或其底层实施)是罪魁祸首.
当我开始改变第一个加密值的大小时,我可以看到第二次加密调用的结果发生了变化.这可能意味着流的某些部分未被正确清除或覆盖.但是FlawedAlgorithm班级使用的流不属于其州; 它们在每次方法调用时重新创建.并且该encryptor对象看起来不像管理自己的流的类型.
有没有其他人遇到类似的问题?是RijndaelManaged类存在缺陷?或者MonoTouch中是否存在一些流和内存管理陷阱,与此加密示例无关?
PS:我已经在iPad和iPad模拟器上测试了这个; 都表现出这种奇怪的行为.
使用.NET加密时,必须始终检查ICryptoTransform.CanReuseTransform(或假设它将返回false).如果它返回false,则您不能重用相同的加密器/解密器,并且必须创建新实例.
跳过此检查意味着框架中的任何更改(或通过配置文件,因为加密是可插入的)可能会在将来破坏您的应用程序.
您可以使用以下内容:
ICryptoTransform Decryptor {
get {
if (decryptor == null || !decryptor.CanReuseTransform)
decryptor = rijndael.CreateDecryptor (key, vector);
return decryptor;
}
}
Run Code Online (Sandbox Code Playgroud)
从加密例程的调用者隐藏这种复杂性.
| 归档时间: |
|
| 查看次数: |
1226 次 |
| 最近记录: |