2016-04-27 10 views
0

私のウェブサイト通知を送信するためにサービスが呼び出す公開ウェブフックがあります。このWebフックでは、暗号化されたトークンが必要です。トークンを取得すると、私は定義済みのキーを使用してそれを復号化し、トークンが私が期待していたものであることを確認します。これは正常に動作します。コードを復号化できない場合の例外を防ぐには?

暗号化されていないトークンまたは悪いトークンが関数に渡されると、もちろん復号化は失敗します。これは正常です。ですが、これが発生した場合、例外が生成されることはありません。もし何人かのハッカーが私のWebフックに対して1秒間に1,000,000回の悪い要求を出し、巨大な例外を処理するために各要求が1秒かかると、サーバがクラッシュします。それは私にcs.Close()The input data is not a complete blockで例外を与えている

public static string Decrypt(string cipherText, string key) 
    { 
     string EncryptionKey = key; 
     cipherText = cipherText.Replace(" ", "+"); 

     //I added this to prevent exception when trying to Convert.FromBase64String() 
     if (cipherText.Length % 4 != 0) 
     { 
      //cipherText must be a length that is a multiple of 4, otherwise it will fail 
      return null; 
     } 

     byte[] cipherBytes = Convert.FromBase64String(cipherText); 
     using (Aes encryptor = Aes.Create()) 
     { 
      Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 
      encryptor.Key = pdb.GetBytes(32); 
      encryptor.IV = pdb.GetBytes(16); 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) 
       { 
        cs.Write(cipherBytes, 0, cipherBytes.Length); 
        cs.Close(); //currently giving exception HERE 
       } 
       cipherText = Encoding.Unicode.GetString(ms.ToArray()); 
      } 
     } 
     return cipherText; 
    } 

私は意図的に非暗号化された文字列を渡す:

はここで、これまでの私の復号化コードです。私はここで正確に何が確認されているのか分からないので、それを防ぐ方法はわかりません。

文字列を復号化できない場合、例外がスローされないように、このコードをどのようにリファクタリングできますか?

+0

あなたの 'cipherBytes'長が' encryptor.BlockSize'で割り切れることを確認する必要があると思います。実際にデータのストリームを処理しようとしている場合、これは面倒かもしれません。しかし、文字列を取っているだけであれば問題ではありません。 –

+0

ハッカーに1,000,000件の不正なリクエストを作成させ、それでも何もしないようにしておけば、あなたはすでに間違ったことをしています。 – NullUserException

答えて

3

あなたは例外をcatchできます。 (ログ、再ルーティング、無視など)。試してみてください:https://msdn.microsoft.com/en-us/library/0yd65esw.aspx

+0

私はtry/catchについて認識していますが、例外を "キャッチ"しても問題は解決しないと思っています。 "ハッカーが1秒でWebフックに対して1,000,000回の悪い要求を作成し、巨大な例外を処理すると、サーバがクラッシュします。 ?? – AlbatrossCafe

+0

@AlbatrossCafeこれは正しい方法です。もちろん、暗号APIを破壊して自分で処理することができるので、例外は発生しませんが、さらに危険な領域に入ります。暗号化を実装します。これははるかに悪いです。必要なように例外を処理し、記述するシナリオを防ぐためにレート制限を実装します。 – NullUserException

0

CBCのような非認証モードで暗号文を解読すると、パディングエラーは間違ったキーや間違った最終ブロックを256回の確率で約255回検出することができます。これは、最終ブロックが破損し、有効なパディングが見つからない場合に発生します。 PKCS#7 paddingはデフォルトで使用され、検証が可能な特別な構造を持っています。

あなたはにどのような方法でアンパディング試みない復号化を要求することができます。

encryptor.Padding = PaddingMode.None; 

が、その後、あなたは(パディングバイトのみ1 AESのための16の範囲内とすることができる)を自分でunpadする必要があります。

var ctBytes = ms.ToArray(); 
var last = ctBytes[ctBytes.Length-1]; 
if (last < 17 && last > 0) { 
    cipherText = Encoding.Unicode.GetString(ctBytes.Take(ctBytes.Length - last)); 
} else { 
    ciphertext = null; 
} 
関連する問題