2016-09-01 10 views
-1

私は情報を提供するためにC#Web APIを実装しました。
この情報は暗号化されており、他のC#またはClassic ASP Webサイトによって消費されます。
Tisは、EncryptRijndaelとDecryptRijndaelメソッドを使用して暗号化/復号化を行う方法です。PHPを使用したC#暗号化の復号化

using System; 
using System.Text; 

namespace Encryption_Test 
{ 
    using System.IO; 
    using System.Security.Cryptography; 
    using System.Text.RegularExpressions; 
    using System.Windows.Forms; 

    class RijndaelManagedEncryption 
    { 
     //http://www.codeproject.com/Tips/704372/How-to-use-Rijndael-ManagedEncryption-with-Csharp 

     #region Rijndael Encryption 

     /// <summary> 
     /// Encrypt the given text and give the byte array back as a BASE64 string 
     /// </summary> 
     /// <param name="text" />The text to encrypt 
     /// <param name="salt" />The pasword salt 
     /// <returns>The encrypted text</returns> 
     public static string EncryptRijndael(string text, string salt, string inputKey) 
     { 
      if (string.IsNullOrEmpty(text)) 
       throw new ArgumentNullException("text"); 

      var aesAlg = NewRijndaelManaged(salt, inputKey); 

      var blockSize = aesAlg.BlockSize; 

      var strK = System.Text.Encoding.ASCII.GetString(aesAlg.Key); 
      string s = strK; 

      var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); 
      var msEncrypt = new MemoryStream(); 
      using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
      using (var swEncrypt = new StreamWriter(csEncrypt)) 
      { 
       swEncrypt.Write(text); 
      } 

      return Convert.ToBase64String(msEncrypt.ToArray()); 
     } 
     #endregion 

     #region Rijndael Dycryption 
     /// <summary> 
     /// Checks if a string is base64 encoded 
     /// </summary> 
     /// <param name="base64String" />The base64 encoded string 
     /// <returns> 
     public static bool IsBase64String(string base64String) 
     { 
      base64String = base64String.Trim(); 
      return (base64String.Length%4 == 0) && 
        Regex.IsMatch(base64String, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None); 

     } 

     /// <summary> 
     /// Decrypts the given text 
     /// </summary> 
     /// <param name="cipherText" />The encrypted BASE64 text 
     /// <param name="salt" /> 
     /// <param name="inputKey"></param> 
     /// The pasword salt 
     /// <returns>De gedecrypte text</returns> 
     public static string DecryptRijndael(string cipherText, string salt, string inputKey) 
     { 
      if (string.IsNullOrEmpty(cipherText)) 
       throw new ArgumentNullException("cipherText"); 

      if (!IsBase64String(cipherText)) 
       throw new Exception("The cipherText input parameter is not base64 encoded"); 

      string text; 

      var aesAlg = NewRijndaelManaged(salt, inputKey); 
      var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); 
      var cipher = Convert.FromBase64String(cipherText); 

      using (var msDecrypt = new MemoryStream(cipher)) 
      { 
       using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
       { 
        using (var srDecrypt = new StreamReader(csDecrypt)) 
        { 
         text = srDecrypt.ReadToEnd(); 
        } 
       } 
      } 
      return text; 
     } 
     #endregion 

     #region NewRijndaelManaged 

     /// <summary> 
     /// Create a new RijndaelManaged class and initialize it 
     /// </summary> 
     /// <param name="salt" /> 
     /// <param name="inputKey"></param> 
     /// The pasword salt 
     /// <returns> 
     private static RijndaelManaged NewRijndaelManaged(string salt, string inputKey) 
     { 
      if (salt == null) throw new ArgumentNullException("salt"); 
      var saltBytes = Encoding.ASCII.GetBytes(salt); 
      var key = new Rfc2898DeriveBytes(inputKey, saltBytes); 

      var aesAlg = new RijndaelManaged(); 
      aesAlg.Key = key.GetBytes(aesAlg.KeySize/8); //256/8 = 32 
      aesAlg.IV = key.GetBytes(aesAlg.BlockSize/8); //128/8 = 16 
      //string k = System.Text.Encoding.Default.GetString(aesAlg.Key); 
      //string i = System.Text.Encoding.Default.GetString(aesAlg.IV); 
      //string l = k + i; 

      #region testPHP 
      ///* 
      // So it would seem the week point in the chain for PHP is the Rfc2898DeriveBytes 
      // */ 
      //aesAlg.Key = Encoding.UTF8.GetBytes(inputKey); 
      //aesAlg.IV = Encoding.UTF8.GetBytes(salt); 

      //k = System.Text.Encoding.Default.GetString(aesAlg.Key); 
      //i = System.Text.Encoding.Default.GetString(aesAlg.IV); 
      //l = k + i; 
      #endregion testPHP 

      return aesAlg; 
     } 
     #endregion 
    } 
} 

あなたは、私はちょうどちょうど[]のバイトにそれらを変換することによって提供されたパラメータからキーとIVを設定し終わりに向かったときにコメントアウトを見ることができます。それはPHPにとっては問題ないと思われますが、Rfc2898DeriveBytesを省略しないでください。

これはうまく動作し、消費するサイトは情報を解読できます。

ここで私は(他の人の問題だが助けたい)、PHPサイトでWeb APIを使用する必要がある。彼らはそれをすることができないようです。彼らは、IVの作成方法に起因するサイトである。

さて、これは

  1. 彼らは私の実装では、それは不可能彼らはそれを行うために作られた仕事
  2. までされていない場合、私は思ってしまいます。

私はPHPについてほとんど知りませんが、一般的にコードブロックの流れに従うことができます。 PHPで目標を達成することが可能かどうか誰にでも教えていただければ幸いです。

注 - これは私が問題の要点であると信じているRfc2898DeriveBytesを利用しており、この質問を他の人と同様に扱っています。

例暗号化するために

  • 文字列:Co-operation is the key to success!
  • 塩:This_is_the_password_salt
  • 入力キー:This_is_the_input_key
  • 暗号化された文字列:まあpLgIEjhNGDMfI0IynoAdbey3NKbOJzgUzYAlU14OWOpuZy7/lr7HRtFhiRKfjbZz
+0

ませんこれはDUPLではありませんicate。 あなたが参照しているものはRfc2898DeriveBytesを利用していません。 それは特にこの作品が問題だと思われます。 – AntDC

+0

@RiggsFolly - 再開してください – AntDC

+0

あなたは実際にデータを暗号化する方法についての十分な情報を提供していないので、助けはほとんど不可能です。他の人があなたのデータを暗号解除しようとしているのを見ることはできません。だから、この質問は、** un unable ** – RiggsFolly

答えて

0

- そのサンドボックスを見つけた後にhash_hmacを取ることができた私はそれをsussed持っているようだあなたたちとあなたのコメント......

this site.

を使用し、その中に次のコード(私はちょうどそれが現実の状況で同じ動作を望む)

<?php 

class Foo { 

public function decrypt_full($key, $iv, $encrypted) 
{ 
$dev = $this->pbkdf2("sha1", $key, $iv, 1000, 48, true); 
$derived_key = substr($dev, 0, 32); //Keylength: 32 
$derived_iv = substr($dev, 32, 16); // IV-length: 16 
return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $derived_key, base64_decode($encrypted), MCRYPT_MODE_CBC, $derived_iv); 
} 

private function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false) 
{ 
$algorithm = strtolower($algorithm); 
if(!in_array($algorithm, hash_algos(), true)) 
die('PBKDF2 ERROR: Invalid hash algorithm.'); 
if($count <= 0 || $key_length <= 0) 
die('PBKDF2 ERROR: Invalid parameters.'); 

$hash_length = strlen(hash($algorithm, "", true)); 
$block_count = ceil($key_length/$hash_length); 

$output = ""; 
for($i = 1; $i <= $block_count; $i++) { 
// $i encoded as 4 bytes, big endian. 
$last = $salt . pack("N", $i); 
// first iteration 
$last = $xorsum = hash_hmac($algorithm, $last, $password, true); 
// perform the other $count - 1 iterations 
for ($j = 1; $j < $count; $j++) { 
$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true)); 
} 
$output .= $xorsum; 
} 
return substr($output, 0, $key_length); 
} 

} 
//########################################################################################### 
$encrypted = "pLgIEjhNGDMfI0IynoAdbey3NKbOJzgUzYAlU14OWOpuZy7/lr7HRtFhiRKfjbZz"; 
$iv = "This_is_the_password_salt"; 
$key = "This_is_the_input_key"; 

$foo = new foo; 
echo "<br/>"; 
echo "Encrypted String: ".$encrypted."<br/>"; 
echo "Decrypted string: ".$foo->decrypt_full($key, $iv, $encrypted)."<br/>"; 
?> 

でオンに拍車をかけ出力が...

Key: .g���13f^sI>M��j$\�+�od�mY# �! 
IV: �2]��&y�q� WJ�� 
Decrypted: Co-operation is the key to success! 

はPHPの男を伝えるために待つことができませんされます。)

+2

出力がぎこちなく表示される理由は、暗号化されたデータが文字列ではないため、印刷可能な表現を持たず、UTF-8などの多くのエンコーディングシステムでも合法的なエンコーディングではない値を含む一見8ビットbtesの配列です。これは、データを表示するために16進数を使用し、データを文字列として送信するためにBase64を使用する理由です。 – zaph

+1

IV '$ iv'は本当に' pbkdf2() 'の塩です。 – zaph

+0

私は、アプリケーションのセキュリティを扱う際に、「動作していると思われる」コードをインターネットからコピーアンドペーストできることを驚かせています。夜はどうやって寝ますか? –

関連する問題