2011-10-09 12 views
3

Openfireは、ブローフィッシュの暗号化を使用して暗号化されたパスワードをデータベースに保存します。PHPを介してopenfire MySQLで暗号化されたパスワードを作成する

http://svn.igniterealtime.org/svn/repos/openfire/trunk/src/java/org/jivesoftware/util/Blowfish.javaは、openfireで暗号化/復号化関数がどのように機能するかについてのJavaの実装です。

私の目標は、PHPとMySQLIを介してデータベースに新しいユーザーエントリを作成することです。私が試みたすべてのバリエーションは、データベースに既に存在するものと一致しない結果をもたらしました。例:

d3f499857b40ac45c41828ccaa5ee1f90b19ca4e0560d1e2dcf4a305f219a4a2342aa7364e9950dbは、暗号化されたパスワードの1つです。 mcrypt blowfish php slightly different results when compared to java and .net

$key = '1uY40SR771HkdDG'; 
$pass = 'stackoverflow'; 
$blocksize = mcrypt_get_block_size('blowfish', 'cbc'); // get block size 
$pkcs = $blocksize - (strlen($data) % $blocksize); // get pkcs5 pad length 
$data.= str_repeat(chr($pkcs), $pkcs); // append pkcs5 padding to the data 

// encrypt and encode 
$res = base64_encode(mcrypt_cbc(MCRYPT_BLOWFISH,$key, $pass, MCRYPT_ENCRYPT)); 
echo $res; 
// result: 3WXKASjk35sI1+XJ7htOGw== 

どれ巧妙なアイデア、または任意の明白な問題に基づいて

echo mcrypt_cbc(MCRYPT_BLOWFISH, '1uY40SR771HkdDG', 'stackoverflow', MCRYPT_ENCRYPT, '12345678'); 
// result: áë*sY¶nŸÉX_33ô 

別:クリアテキストでは、これはstackoverflow

である私は、いくつかのバリエーションを試してみましたか?私は単にBlowfish.encryptString()をこの質問の最初のリンクで参照して実装したいと思います。

+1

最も目立つ問題は、パスワードをハッシュ*する代わりに*暗号化していることです。 **絶対にパスワードが必要な場合を除き、パスワードを元の形式にしてはいけません。 – NullUserException

+1

XMPPプロトコルでは、クリアテキストを使用してユーザーを認証します。そのため、Openfireでは暗号化/復号化が必要です。ちょうど私が持っているもので動作しようとしている... – sdolgy

+0

それは何が生成するためのいくつかのテストベクトルを持っていますか?キー、iv、データおよび暗号文の組み合わせ – Ivo

答えて

6

私が作ったクラスは、正しく暗号化され、復号化されます。

結果を再現するには、/ [pre/app]を保存してIVを終了する必要があります。

Javaコードのいくつかのテストベクタは素晴らしいでしょう。

<?php 

/** 
* Emulate OpenFire Blowfish Class 
*/ 
class OpenFireBlowfish 
{ 
    private $key; 
    private $cipher; 

    function __construct($pass) 
    { 
     $this->cipher = mcrypt_module_open('blowfish','','cbc',''); 
     $this->key = pack('H*',sha1($pass)); 
    } 

    function encryptString($plaintext, $iv = '') 
    { 
     if ($iv == '') { 
      $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->cipher)); 
     } 
     else { 
      $iv = pack("H*", $iv); 
     } 
     mcrypt_generic_init($this->cipher, $this->key, $iv); 
     $bs = mcrypt_enc_get_block_size($this->cipher); // get block size 
     $plaintext = mb_convert_encoding($plaintext,'UTF-16BE'); // set to 2 byte, network order 
     $pkcs = $bs - (strlen($plaintext) % $bs); // get pkcs5 pad length 
     $pkcs = str_repeat(chr($pkcs), $pkcs); // create padding string 
     $plaintext = $plaintext.$pkcs; // append pkcs5 padding to the data 
     $result = mcrypt_generic($this->cipher, $plaintext); 
     mcrypt_generic_deinit($this->cipher); 
     return $iv.$result; 
    } 

    function decryptString($ciphertext) 
    { 
     $bs = mcrypt_enc_get_block_size($this->cipher); // get block size 
     $iv_size = mcrypt_enc_get_iv_size($this->cipher); 
     if ((strlen($ciphertext) % $bs) != 0) { // check string is proper size 
      return false; 
     } 
     $iv = substr($ciphertext, 0, $iv_size); // retrieve IV 
     $ciphertext = substr($ciphertext, $iv_size); 
     mcrypt_generic_init($this->cipher, $this->key, $iv); 
     $result = mdecrypt_generic($this->cipher, $ciphertext); // decrypt 
     $padding = ord(substr($result,-1)); // retrieve padding 
     $result = substr($result,0,$padding * -1); // and remove it 
     mcrypt_generic_deinit($this->cipher); 
     return $result; 
    } 

    function __destruct() 
    { 
     mcrypt_module_close($this->cipher); 
    } 
} 

$enckey = "1uY40SR771HkdDG"; 
$enciv = 'd3f499857b40ac45'; 
$javastring = 'd3f499857b40ac45c41828ccaa5ee1f90b19ca4e0560d1e2dcf4a305f219a4a2342aa7364e9950db'; 

$a = new OpenFireBlowfish($enckey); 
$encstring = bin2hex($a->encryptString('stackoverflow',$enciv)); 
echo $encstring . "\n"; 
echo $a->decryptString(pack("H*", $encstring)) . "\n"; 

$b = new OpenFireBlowfish($enckey); 
echo $b->decryptString(pack("H*", $javastring)) . "\n"; 
+0

Ivo、これに感謝します。しかし、 'd3f499857b40ac45c41828ccaa5ee1f90b19ca4e0560d1e2dcf4a305f219a4a2342aa7364e9950db'は私の例では' stackoverflow'が暗号化されていますが、これは指定された情報で解読されません。 – sdolgy

+0

これはどのエンコーディングを使用していますか?それは非常に長いstackoverflowを行うには見える – Ivo

+0

注意してください、それはまさに右ではない場合は...私は間違ったキーで何かを解読するためにそれを伝える、現在のところです。 – Ivo

1

Openfireのコードは、渡されたCBCIVに出力文字列を付加します。また、Unicodeを文字セットとして使用します。これらは一緒に問題の領域かもしれません。

私はブローフィッシュの内部についてもっと知りません。申し訳ありません。

1

コードに間違いはありませんが、Openfireと同じコードを生成するには、暗号化されたテキストの前に他の2つの項目を追加する必要があります。

  • Javaコードで暗号文の長さ
  • CBCIV(初期化変数)

読む "公共の文字列decryptString(文字列sCipherText)"、それはすべてがあります。また、PHPでCBCIVを使用する方法については、ドキュメントをチェックしてください。

関連する問題