2017-03-24 6 views
0

他のアプリケーションのデータを一部解読するColdFusionページがあります。 ColdFusionコードはかなり簡単です:RC4/Hexを使用して、ColdFusionからDecrypt関数を.NETに変換します。

decrypt(theString,encryptKey,algorithmType,encodeType) 

アルゴリズムタイプはRC4で、エンコードタイプは16進数です。何らかの理由で私はこれをネットで動かすのにかなり手間がかかります。この種のものに利用できるリソースはありますか、それともかなり簡単な答えがありますか?

更新:RC4 Encryption in C#

私はここで見つけるRC4クラスを使用し始めました。エンコーディングをAsciiに変更しましたが、結果はまだ一致しません。

public static class RC4 
{ 
    public static string Encrypt(string key, string data) 
    { 
     Encoding unicode = Encoding.Unicode; 

     return Convert.ToBase64String(Encrypt(unicode.GetBytes(key), unicode.GetBytes(data))); 
    } 

    public static string Decrypt(string key, string data) 
    { 
     Encoding unicode = Encoding.Unicode; 

     return unicode.GetString(Encrypt(unicode.GetBytes(key), Convert.FromBase64String(data))); 
    } 

    public static byte[] Encrypt(byte[] key, byte[] data) 
    { 
     return EncryptOutput(key, data).ToArray(); 
    } 

    public static byte[] Decrypt(byte[] key, byte[] data) 
    { 
     return EncryptOutput(key, data).ToArray(); 
    } 

    private static byte[] EncryptInitalize(byte[] key) 
    { 
     byte[] s = Enumerable.Range(0, 256) 
     .Select(i => (byte)i) 
     .ToArray(); 

     for (int i = 0, j = 0; i < 256; i++) 
     { 
     j = (j + key[i % key.Length] + s[i]) & 255; 

     Swap(s, i, j); 
     } 

     return s; 
    } 

    private static IEnumerable<byte> EncryptOutput(byte[] key, IEnumerable<byte> data) 
    { 
     byte[] s = EncryptInitalize(key); 

     int i = 0; 
     int j = 0; 

     return data.Select((b) => 
     { 
     i = (i + 1) & 255; 
     j = (j + s[i]) & 255; 

     Swap(s, i, j); 

     return (byte)(b^s[(s[i] + s[j]) & 255]); 
     }); 
    } 

    private static void Swap(byte[] s, int i, int j) 
    { 
     byte c = s[i]; 

     s[i] = s[j]; 
     s[j] = c; 
    } 
} 
+0

問題の詳細について教えてください。 – rossum

+0

何を試しましたか?そのアルゴリズムはコアライブラリの一部ではないようですが、クイック検索でカスタム実装がいくつか登場しました。後方互換性の理由からRC4を維持する必要があると仮定していますか? – Leigh

+0

奇妙なことに、RC4は、暗号化のCFドキュメンテーションがありますが、復号化はできません。なぜそうなるのか分かりません。 – Josh

答えて

0

更新:

"エンコードタイプは、" 実際にbase64で(ない進)であれば、それはさらに簡単です。 Encrypt()関数を変更して、結果をbase64としてエンコードします。次に、Decrypt()関数を変更して、両方の値をから base64にデコードします。

public static string Encrypt(string base64Key, string plainText) 
{ 

    return Convert.ToBase64String(Encrypt(Convert.FromBase64String(base64Key), Encoding.UTF8.GetBytes(plainText))); 
} 

public static string Decrypt(string base64Key, string base64Encrypted) 
{ 
    return Encoding.UTF8.GetString(Encrypt(Convert.FromBase64String(base64Key), Convert.FromBase64String(base64Encrypted))); 
} 

私はASCIIにエンコーディングを変更しました。

閉じるが、それでも入力を正しく復号化することはできません。したがって、クラスは最終的に間違ったバイナリを暗号化/復号化し、失敗させます。完全にCFを複製するために、あなたは彼らがパラメータデコード方法を理解し必要な機能:

同じことをするには、C#クラスを変更する必要があります。

public static string ByteArrayToHex(byte[] ba) 
{ 
    string hex = BitConverter.ToString(ba); 
    return hex.Replace("-", ""); 
} 

public static byte[] HexToByteArray(string hex) 
{ 
    return Enumerable.Range(0, hex.Length) 
        .Where(x => x % 2 == 0) 
        .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) 
        .ToArray(); 
} 
  • BASE64などの主要および六角として暗号化されたテキストを復号化する復号化()関数を変更します。convert a byte[] to hexconvert hex to a byte[]は、ヘルパー関数を作成することによって、

    1. スタート。最後に、復号化された値をUTF-8文字列として返します。

      public static string Decrypt(string base64Key, string hexValue) 
      { 
          return Encoding.UTF8.GetString(Encrypt(Convert.FromBase64String(base64Key), HexToByteArray(hexValue))); 
      } 
      
    2. キーをbase64として、プレーンテキストをUTF-8としてデコードするようにEncrypt機能を変更します。その後、暗号化された値を16進数で返します。これらの小さな変化で

      public static string Encrypt(string base64Key, string plainText) 
      { 
      
          return ByteArrayToHex(Encrypt(Convert.FromBase64String(base64Key), Encoding.UTF8.GetBytes(plainText))); 
      } 
      

    、C#コードは、CF機能と同じ結果を生成します。

    NB:known issues with RC4を読んで、AESなどのより安全なアルゴリズムに切り替えることをおすすめします。

  • +0

    ほぼ完璧です。このように動作させるために、私は16進数のサブを削除し、このようにdecrypt関数からBase64に置き換えました:return Encoding.UTF8.GetString(Encrypt(Convert.FromBase64String(base64Key)、Convert.FromBase64String(hexValue))));その後、それは完全に働いた。ありがとうございました!!! – Josh

    +0

    ああ、大丈夫です。質問の説明によると、復号化関数は16進数の文字列を受け取っていた、つまり、 "* ...エンコードの種類は16進数*です。しかし、あなたが理解したように、バイナリはエンコーディングではなく重要です。値を正しくエンコードすると、使用するもの(base64、hex、etcetera)と実際には違いはありません。 – Leigh

    関連する問題