web-dev-qa-db-ja.com

MySQL AES_ENCRYPTキーの長さ

AES_ENCRYPTは128ビット長のキーを使用してデータを暗号化しますが、MySQLはより長いまたはより短いキーをどのように処理しますか?インスタンスのPyCryptoは、MD5、SHA-1、SHA-2などのハッシュを使用してキーを変換し、結果のキーを暗号化に使用することをお勧めします。 MySQLではどのように機能しますか?

6
joecks

すみませんが、後で RubyForum からそれを見つけました

「アルゴリズムは、すべて0に設定された16バイトのバッファーを作成し、指定した文字列のすべての文字をループして、2つの値の間にビット単位のXORを使用して割り当てを行います。 16バイトのバッファの終わりに到達したら、^ =を実行して最初からやり直します。16文字より短い文字列の場合は、文字列の終わりで停止します。」

  bzero((char*) rkey,AES_KEY_LENGTH/8);      /* Set initial key  */

  for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++)
  {
    if (ptr == rkey_end)
      ptr= rkey;  /*  Just loop over tmp_key until we used all key */
    *ptr^= (uint8) *sptr;
  }

rubyのように見える

def mysql_key2(key)
   final_key = "\0" * 16
   key.length.times do |i|
     final_key[i%16] ^= key[i]
   end
   final_key
end

そして私はそれをPythonに適用しました:

finalKey = b'\0'*16
key = b'mySecretKey'
for i, c in enumerate(key) :
  finalKey[i%16] ^= key[i]

結果のキーがゼロになるため、"MySQL=insecure! MySQL=insecure! "などの反復的なパスワードを使用しない方が賢明です。

4
joecks

MySQL 5.5は他のキーサイズを処理しません。 http://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html で述べたように:

AES_ENCRYPT()およびAES_DECRYPT()は、以前は「Rijndael」と呼ばれていた公式のAES(Advanced Encryption Standard)アルゴリズムを使用して、データの暗号化と復号化を可能にします。 128ビットのキー長でのエンコードが使用されますが、ソースを変更することにより、最大256ビットに拡張できます。 128ビットを選択した理由は、はるかに高速であり、ほとんどの目的で十分に安全であるためです。

大きなキーをMySQLに渡そうとしたことはありませんが、エラーが発生するか、128ビットに切り捨てられると思います。

MD5が完全なコドメインであるかどうかは、MD5が推測であるという証拠を見つけることができないため、わかりません。したがって、キーの可能な値のセットを減らすことで、MD5ハッシュを使用することでlessセキュリティが得られると思います。これはまだ非常に主観的です。

小さいキーに関する限り、私は0x1 == 0x00...01したがって、それはまだ有効なキーです。

ところで、なぜ指定されたサイズのキーを生成しないのかわかりません。いくつかの制約がある場合(再利用したい既存のキーなど)は、お知らせください。

3
M'vy

これをPHPで行う必要がありました。 @joecksの説明に従ってXORを実行し、ここで説明するように16バイトより短い暗号化データのパディングを削除する必要があります。 http://forums.devnetwork.net/viewtopic .php?f = 34&t = 97082

作業コード:

<?php
    $key = 'SomeSecretKeyThatCanBeLongerThan16Bytes';
    $encodedString = [fetched from DB];

    $finalKey = array_fill(0, 16, 0);
    foreach (unpack('C*', $key) as $i => $char)
    {
        $finalKey[($i-1)%16] = $finalKey[($i-1)%16] ^ $char;
    }

    $dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, implode(array_map("chr", $finalKey)), $encodedString, MCRYPT_MODE_ECB, '');
    return rtrim($dec, ((ord(substr($dec, strlen($dec) - 1, 1)) >= 0 and ord(substr($dec, strlen($dec) - 1, 1 ) ) <= 16 ) ? chr(ord(substr($dec, strlen($dec ) - 1, 1))): null) );
0
Whisk

デフォルトでは、これらの関数は128ビットのキー長のAESを実装しています。 MySQL 5.7.4以降では、後で説明するように、196または256ビットのキー長を使用できます。キーの長さは、パフォーマンスとセキュリティの間のトレードオフです。 暗号化関数

0
SQLey.com