2016-09-01 3 views
-1

얼마 전에 정보를 제공하기 위해 C# 웹 API를 구현했습니다.
이 정보는 암호화되어 다른 C# 또는 Classic ASP 웹 사이트에서 사용됩니다.
Tis는 EncryptRijndael 및 DecryptRijndael 메서드를 사용하여 암호화/암호 해독을 수행하는 방법입니다.PHP로 암호 해독

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 
    } 
} 

당신이 때 I는 그냥 [] 바이트들을 변환하여 제공되는 파라미터들로부터 키와 IV를 설정 말로 주석 볼 수있다. PHP에서는 괜찮은 것처럼 보이지만 Rfc2898DeriveBytes를 생략하지는 않을 것입니다.

잘 작동하며 소비 사이트는 정보를 해독 할 수 있습니다.

이제 내 (다른 사람의 문제이지만 도움을주고 싶습니다.) PHP 사이트에서 내 웹 API를 사용해야합니다. 그들은 그것을 할 수없는 것 같습니다. 그들은 IV가 만들어지는 방식에 기인한다고 생각합니다.

지금이 그들은 내 구현이 불가능 그들이 그것을 할 수했다

  • 일까지없는

    1. 경우 나 궁금합니다.

    이제 PHP에 대해서는 거의 알지 못하지만 일반적으로 코드 블록의 흐름을 따라갈 수 있습니다. PHP를 사용하여 목표를 달성 할 수있는 사람이 누구인지 먼저 말할 수 있다면 감사하겠습니다. 그렇다면 어쩌면 그렇게하는 방법에 대한 지침이 될 것입니다.

    주 -이 질문은 Rfc2898DeriveBytes를 사용하여이 질문의 핵심이며이 질문을 다른 사람들과 유사하게 설명합니다.

    • 문자열 암호화하기 : Co-operation is the key to success!
    • 소금 : This_is_the_password_salt
    • 입력 키 : This_is_the_input_key
    • 암호화 된 문자열 : pLgIEjhNGDMfI0IynoAdbey3NKbOJzgUzYAlU14OWOpuZy7/lr7HRtFhiRKfjbZz
  • +0

    없음이이 DUPL 아니다 출력은

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

    는 PHP들에게 기다릴 수

    은 ...입니다 icate. 참조한 것이 Rfc2898DeriveBytes를 사용하지 않습니다. 그리고이 조각이 특히 문제인 것처럼 보입니다. – AntDC

    +0

    @RiggsFolly - 다시 열기 – AntDC

    +0

    실제로 데이터를 암호화하는 방법에 대한 정보가 충분하지 않으므로 도움이 거의 불가능합니다. 당신은 또한 문제가있는 사람이 아니므로 다른 사람들이 귀하의 데이터를 암호 해독하려고 시도하는 것을 볼 수 없습니다. 그래서이 질문은 ** 답할 수없는 종류의 ** ** – 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/>"; 
    ?> 
    

    에 의해 박차)

    +2

    출력이 횡설수설하는 이유는 암호화 된 데이터가 문자열이 아니기 때문입니다. 인쇄 가능한 표현이없고 UTF-8과 같은 많은 인코딩 시스템에서 올바른 인코딩이 아닌 값을 포함한 겉으로보기에는 8 비트 btes의 배열입니다. 이것은 데이터를 표시하는 데 일반적으로 16 진수를 사용하고 데이터를 문자열로 전송하는 데 Base64를 사용하는 이유입니다. – zaph

    +1

    IV'$ iv '라고 부르는 것은 실제로'pbkdf2()'의 소금입니다. – zaph

    +0

    사람들이 응용 프로그램의 보안을 처리 할 때 "작동하는 것"이라는 인터넷 코드를 복사하여 붙여 넣기 할 수 있다는 점은 놀랍습니다. 밤에 어떻게 자니? –