2016-10-10 4 views
0

に弾む城を使用して暗号化とこれは私が使用していたコードのPHPコードはC#で、私はデータの暗号化と復号化にC#で快活なお城と、次のコードを使用していますC#とPHP

public static string BCEncrypt(string input) 
{ 
    string keyString = "mysecretkey12345"; 
    string keyStringBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(keyString)); 
    byte[] inputBytes = Encoding.UTF8.GetBytes(input); 
    byte[] iv = new byte[16]; 

    //Set up 
    AesEngine engine = new AesEngine(); 
    CbcBlockCipher blockCipher = new CbcBlockCipher(engine); //CBC 
    PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding()); 
    //PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher); //Default scheme is PKCS5/PKCS7 
    KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(keyStringBase64)); 
    ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv, 0, 16); 

    // Encrypt 
    cipher.Init(true, keyParamWithIV); 
    byte[] outputBytes = new byte[cipher.GetOutputSize(inputBytes.Length)]; 
    int length = cipher.ProcessBytes(inputBytes, outputBytes, 0); 
    cipher.DoFinal(outputBytes, length); //Do the final block 
    return Convert.ToBase64String(outputBytes); 
} 

public static string BCDecrypt(string input) 
{ 
    string keyString = "mysecretkey12345"; 
    string keyStringBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(keyString)); 
    byte[] inputBytes = Encoding.UTF8.GetBytes(input); 
    byte[] iv = new byte[16]; 
    //Set up 
    AesEngine engine = new AesEngine(); 
    CbcBlockCipher blockCipher = new CbcBlockCipher(engine); //CBC 
    PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher); //Default scheme is PKCS5/PKCS7 
    KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(keyStringBase64)); 
    ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv, 0, 16); 

    //Decrypt    
    byte[] outputBytes = Convert.FromBase64String(input); 
    cipher.Init(false, keyParamWithIV); 
    byte[] comparisonBytes = new byte[cipher.GetOutputSize(outputBytes.Length)]; 
    int length = cipher.ProcessBytes(outputBytes, comparisonBytes, 0); 
    cipher.DoFinal(comparisonBytes, length); //Do the final block 
    return System.Text.Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length); 
} 

を復号化:

<? 
    function encrypt($input, $key) { 
     $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); 
     $input = Security::pkcs5_pad($input, $size); 
     $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, ''); 
     $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 
     mcrypt_generic_init($td, $key, $iv); 
     $data = mcrypt_generic($td, $input); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td); 
     $data = base64_encode($data); 
     return $data; 
    } 

    function pkcs5_pad ($text, $blocksize) { 
     $pad = $blocksize - (strlen($text) % $blocksize); 
     return $text . str_repeat(chr($pad), $pad); 
    } 

    function decrypt($sStr, $sKey) { 
     $decrypted= mcrypt_decrypt(
      MCRYPT_RIJNDAEL_128, 
      $sKey, 
      base64_decode($sStr), 
      MCRYPT_MODE_ECB 
     ); 
     $dec_s = strlen($decrypted); 
     $padding = ord($decrypted[$dec_s-1]); 
     $decrypted = substr($decrypted, 0, -$padding); 
     return $decrypted; 
    } 

    echo "Input: " . $_REQUEST["inp"] . "<br>Decrypt: ". decrypt($_REQUEST["inp"], 'mysecretkey12345')."<br>"; 
    ?> 

私は、このような「greatscott」私は、次の結果を得るように、C#を使用して、短い文字列を暗号化しようとすると:dSk7z0F4JYsc0zhl95 + YMWの==

これは、PHPのコードを使用して[OK]を復号化します。

は、しかし、私は、「これは非常に長い文字列である」などのC#コードを使用して長い文字列を暗号化しようとすると、私は次のような結果を得る:xcL4arrFD8Fie73evfHjvUjNEmZrA9h6SmO0ZRE82Hw =

そして、これは解読されません。暗号化された文字列の最初の半分は同じだが後半は同じではないので、同じ文字列を暗号化しようとすると "これは非常に長い文字列です"というメッセージが表示されます。これは私がパディングが間違っているか何かを持っていると思うようにする。

アドバイスをいただければ幸いです。

ありがとうございました

+0

PHPで暗号化と復号化にopensslを使用します。 –

+3

PHPコードでECBモードを使用し、C#コードでCBCモードを使用しています。また、C#の暗号化関数ではすべてゼロのIVを使用していますが、PHPコードではIVをランダムに使用しています。どちらのコードでもIVを送信していません。あなたはここで間違っている。 –

+0

CTRモードを使用します。他のモードについて聞いたことはありません。 – Ben

答えて

0

ルークとジェームズさんに感謝します。

私は現在、PHPで暗号化と復号化にopensslを使用しています。私はランダムIVを生成し、復号化のためにシステム間を前後に渡しています。

これは私が今使っているコードです:

C#の

public static string BCEncrypt(string input, out string iv_base64) 
{ 
    byte[] inputBytes = Encoding.UTF8.GetBytes(input); 
    SecureRandom random = new SecureRandom(); 
    byte[] iv = new byte[16]; 
    random.NextBytes(iv); 
    iv_base64 = Convert.ToBase64String(iv); 
    string keyString = "mysecretkey12345"; 
    string keyStringBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(keyString)); 

    //Set up 
    AesEngine engine = new AesEngine(); 
    CbcBlockCipher blockCipher = new CbcBlockCipher(engine); //CBC 
    PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding()); 
    KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(keyStringBase64)); 
    ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv, 0, 16); 

    // Encrypt 
    cipher.Init(true, keyParamWithIV); 
    byte[] outputBytes = new byte[cipher.GetOutputSize(inputBytes.Length)]; 
    int length = cipher.ProcessBytes(inputBytes, outputBytes, 0); 
    cipher.DoFinal(outputBytes, length); //Do the final block 
    return Convert.ToBase64String(outputBytes); 
} 

public static string BCDecrypt(string input, string iv_base64) 
{ 
    string keyString = "mysecretkey12345"; 
    string keyStringBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(keyString)); 
    byte[] inputBytes = Encoding.UTF8.GetBytes(input); 
    byte[] iv = Convert.FromBase64String(iv_base64); 
    //Set up 
    AesEngine engine = new AesEngine(); 
    CbcBlockCipher blockCipher = new CbcBlockCipher(engine); //CBC 
    PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding()); 
    KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(keyStringBase64)); 
    ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv, 0, 16); 

    //Decrypt    
    byte[] outputBytes = Convert.FromBase64String(input); 
    cipher.Init(false, keyParamWithIV); 
    byte[] comparisonBytes = new byte[cipher.GetOutputSize(outputBytes.Length)]; 
    int length = cipher.ProcessBytes(outputBytes, comparisonBytes, 0); 
    cipher.DoFinal(comparisonBytes, length); //Do the final block 
    return Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length); 
} 

PHP側は次のようになり

$iv = base64_decode($iv_base64); 
$method = "aes-128-cbc"; 
$password = "mysecretkey12345"; 
$decrypted = openssl_decrypt($data, $method, $password,0, $iv); 

およびIVを生成し、PHPで文字列を暗号化するために私は使用しています:

$iv = openssl_random_pseudo_bytes(16) 
$encrypted = openssl_encrypt("something interesting", $method, $password,0,$iv); 

私は今C#またはPHPで暗号化し、C#またはPHPで復号化できるようになりました。

httpsを使用して、2つのシステム間で暗号化されたベース64と暗号化された文字列を渡します。

このソリューションに関するご意見はありますか? (セキュリティなど)

関連する問題