2013-09-04 2 views
6

私はこの関数をC#で書き直そうとしています。しかし、C#の出力は、あなたのC#コードでPHPC#でのMCRYPT_RIJNDAEL_128の暗号化

PHPのバージョン

// Encrypt data using AES128-cbc 
function encrypt($data, $key, $iv) { 
    $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', ''); 
    mcrypt_generic_init($cipher, $key, $iv); 
    $multipass = mcrypt_generic($cipher, $data); 
    mcrypt_generic_deinit($cipher); 
    return $multipass; 
} 

C#バージョン

public static string encrypt(string encryptionString, string iv, string key) 
{ 
    byte[] clearTextBytes = Encoding.UTF8.GetBytes(encryptionString); 
    var rijn = SymmetricAlgorithm.Create(); 
    rijn.KeySize = 128; 
    rijn.Mode = CipherMode.CBC; 
    var ms = new MemoryStream(); 
    var cs = new CryptoStream(ms, rijn.CreateEncryptor(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(iv)), CryptoStreamMode.Write); 
    cs.Write(clearTextBytes, 0, clearTextBytes.Length); 
    cs.Close(); 
    var tmp = Encoding.UTF8.GetString(ms.ToArray()); 
    return tmp; 
} 
+0

は、なぜあなたはそれらの' CryptoStream' + 'MemoryStream'フープを介してジャンプします.TransformFinalBlock'? – CodesInChaos

+0

これを動作させようとしている他の人には、PaddingMode.Zeros(以下のSyonの答え)が私にとっての解決策でした。 –

答えて

6

暗号化/復号化使用してPHP:

class Cipher { 
    private $key, $iv; 
    function __construct() { 
     $this->key = "edrtjfjfjlldldld"; 
     $this->iv = "56666852251557009888889955123458"; 
    } 
    function encrypt($text) { 

     $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); 
     $padding = $block - (strlen($text) % $block); 
     $text .= str_repeat(chr($padding), $padding); 
     $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->key, $text, MCRYPT_MODE_CBC, $this->iv); 

     return base64_encode($crypttext); 
    } 

    function decrypt($input) { 
     $dectext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->key, base64_decode($input), MCRYPT_MODE_CBC, $this->iv); 
     return $dectext; 
    } 
} 

暗号化/復号化使ってC#:あなたは、単に `Rijnにを呼び出すことができるとき

public class RijndaelSimple 
    { 
     const string iv = "56666852251557009888889955123458"; 
     const string key = "edrtjfjfjlldldld"; 

     static public String EncryptRJ256(string plainText) 
     { 
      var encoding = new UTF8Encoding(); 
      var Key = encoding.GetBytes(key); 
      var IV = encoding.GetBytes(iv); 
      byte[] encrypted; 

      using (var rj = new RijndaelManaged()) 
      { 
       try 
       { 
        rj.Padding = PaddingMode.PKCS7; 
        rj.Mode = CipherMode.CBC; 
        rj.KeySize = 256; 
        rj.BlockSize = 256; 
        rj.Key = Key; 
        rj.IV = IV; 

        var ms = new MemoryStream(); 

        using (var cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write)) 
        { 
         using (var sr = new StreamWriter(cs)) 
         { 
          sr.Write(plainText); 
          sr.Flush(); 
          cs.FlushFinalBlock(); 
         } 
         encrypted = ms.ToArray(); 
        } 
       } 
       finally 
       { 
        rj.Clear(); 
       } 
      } 

      return Convert.ToBase64String(encrypted); 
     } 

     static public String DecryptRJ256(string input) 
     { 
      byte[] cypher = Convert.FromBase64String(input); 

      var sRet = ""; 

      var encoding = new UTF8Encoding(); 
      var Key = encoding.GetBytes(key); 
      var IV = encoding.GetBytes(iv); 

      using (var rj = new RijndaelManaged()) 
      { 
       try 
       { 
        rj.Padding = PaddingMode.PKCS7; 
        rj.Mode = CipherMode.CBC; 
        rj.KeySize = 256; 
        rj.BlockSize = 256; 
        rj.Key = Key; 
        rj.IV = IV; 
        var ms = new MemoryStream(cypher); 

        using (var cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read)) 
        { 
         using (var sr = new StreamReader(cs)) 
         { 
          sRet = sr.ReadLine(); 
         } 
        } 
       } 
       finally 
       { 
        rj.Clear(); 
       } 
      } 

      return sRet; 
     } 

    } 
4

2つの問題がミスマッチ。

  1. MemoryStreamの内容をUTF8にエンコードしないでください。 CryptoStreamの出力はバイナリであり、正しく変換されません。 byte[]を返すか、実際に文字列が必要な場合は、出力をHexまたはBase64にエンコードします。

  2. rijn.Padding = PaddingMode.Zeros;でパディングモードを設定する必要があります。明確に記述されていませんが、PHPは0を使用してブロックサイズまでデータを埋め込みます。 SymmetricAlgorithmのパディングのデフォルトはPKCS7です。

また、PHPとC#のメソッドのシグネチャが異なることにも注意してください。 PHP関数のパラメータの順序はdata, key, ivで、C#のメソッドはdata, iv, keyです。上記の変更を行っても問題が解決しない場合は、C#の暗号化メソッドを呼び出すときにIVとキーが逆転している可能性があります。

+0

@nullException:これで問題は解決しないのですか?あなたのコードでこれらの変更をテストすることは、私にとってそれを修正します。 – Syon

+0

+1あなたのアイテム2は良い点ですが、MeladのソリューションではPKCS7のパディングもテキストに追加しています(後で削除する必要があります)ので、結果はC#とPHPの両方で同じになるはずです(同じ結果が両方で得られます) – AaA

+0

@Syon +1 ... PaddingMode.Zerosは私にとっては問題でしたが、私は別の場所でそのチップを見つけました。あなたの答えはより多くのアップフォートを必要とします! –