私は、次の(トリムダウン)クラスを使用して、iPadアプリからWCF Webサービスにデータを送信する前に、データを暗号化しています。MonoTouchで1つの暗号化装置を使用して複数の文字列を暗号化できないのはなぜですか?
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();
}
}
次のコードをサーバーとiPadで実行すると、両方とも同じ暗号化された文字列が印刷されます。
var algorithm = new FlawedAlgorithm();
Console.WriteLine(algorithm.Encrypt("Some string"));
ただし、2番目の値を暗号化しようとすると、サーバーと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"));
私は、サーバー上の逸脱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"));
この問題は関連するオブジェクトの状態のどこかにあると思うように私をリード。 Encrypt(string)
メソッドでbuffer
変数を調べて、UTF8Encoding
インスタンスによって生成された値が正しいことを確認しました。これは、encryptor
フィールド(またはその基礎となる実装)が原因であることを意味します。
最初の暗号化された値のサイズを変更すると、2番目の暗号化呼び出しの結果に変化が見られます。これはおそらく、ストリームの一部が適切に消去または上書きされていないことを意味します。しかし、FlawedAlgorithm
クラスが使用するストリームは、その状態の一部ではありません。それぞれのメソッド呼び出しで再作成されます。 encryptor
オブジェクトは、独自のストリームを管理するタイプのようには見えません。
誰かにこれに類似した問題が発生しましたか? RijndaelManaged
クラスに欠陥がありますか?または、この暗号化の例とは無関係に、MonoTouchにストリームやメモリ管理の落とし穴がありますか?
P .:私はこれをiPadとiPad Simulatorの両方でテストしました。どちらもこの奇妙な動作を表示します。
私に 'CanReuseTransform'プロパティを指摘してくれてありがとう。 .NETでは、falseを返します。モノで、実際にはtrueを返します。それは私が再び作ってくれる間違いです! –
最近、CanReuseTransformはiOS 10 MonoTouchではfalse、Android 7 MonoDroidではtrueです。それでもOPの質問とこの答えは、さらに無礼な苦痛の週末から私を救った。両方のおかげで! –