AES暗号のAES_KEYについて

このQ&Aのポイント
  • AES暗号のAES_KEYについて質問する
  • AES_set_encrypt_key関数のkey配列とivec配列を変更しても暗号後の文字列が変化しない
  • AES_KEYのroundsの値が常に一定であることが問題で、別のコーディングが必要かどうかを知りたい
回答を見る
  • ベストアンサー

AES暗号にて、AES_set_encrypt_keyで設定されるAES_KEYについて

VC++2008にてopensslを用いて、AES暗号/復号の機能を作成しています。 AES_set_encrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_ENCRYPT)にて暗号、 AES_set_decrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_DECRYPT)にて復号するコーディングをしました。 (http://d.hatena.ne.jp/hnko/20090302/1235977892のenc_aes128_cbc_test()を参考にしましたので、 一連の流れは、こことほぼ同じです) デバッグしてみると、一見、暗復号が問題なく出来ていたので、 AES_set_encrypt_key関数の第一引数のkey配列の値と、 ivec配列の値を変えて、デバッグしてみたところ、 key配列を変更すると、暗号化後の文字列も変更されますが、 ivec配列を変更しても、暗号後の文字列に変化が有りませんでした。 調べてみたところ、AES_set_encrypt_keyにて返される AES_KEYのroundsの値が常に同じであることが原因と思われますが、 roundsの値が常に一定だと、暗号解読が比較的容易に 出来てしまうと思うのですが、上記で挙げたサイトでの コーディングの他に、何か別にコーディングを足さなければならないのでしょうか? よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8519/19367)
回答No.1

>ivec配列を変更しても、暗号後の文字列に変化が有りませんでした。 初期ベクタを変えれば必ず暗号文が変化する筈。 変わらないとしたら、初期ベクタを変えているつもりで変わってないだけ。 因みに、初期ベクタは、1ブロック暗号化するたびに内容が更新されていくので、使い方を間違えないように。 >roundsの値が常に一定だと、暗号解読が比較的容易に 暗号鍵を変えればAES_KEYの内容も変化する筈。 変わらないとしたら、暗号鍵を変えているつもりで変わってないだけ。

lhouse
質問者

お礼

AES128のサンプルを256に変更した際に、 ivec配列を[18]から[36]の配列にしたのが原因でした key配列は[18]から[36]でOKだったので、 深く考えずに、ivecも合わせてしまっていました。 bitにかかわらず、[18]の配列みたいですね。 18以降の要素を変更してテストしていたので、 暗号文字列が変わらなかったようです。

関連するQ&A

  • 暗号キーの保存

    現在下記のようにし、暗号化を行っています。 -------------------------以下ソース KeyGenerator kg = KeyGenerator.getInstance("AES"); SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); // 128ビットで暗号化 kg.init(128, random); Key key = kg.generateKey(); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); // バイト配列に変換 byte[] byteArray = cipher.doFinal(argStr.getBytes()); 暗号化について調べていると、暗号化(復号化)キーは乱数などで作ったほうが良いと書いてありました。 そこで質問なのですが、ログイン画面でパスワードを暗号化するために上記コーディングを行っているのですが、乱数でキーを作成した場合、各ユーザごとにキーが作成されるって認識であってますでしょうか? その場合、暗号キーはどこに保存しておくのが望ましいでしょうか? できる限りセキュアなアプリを作りたいと思っています。 (もちろん100%はないとは思っていますので) ※データベースは使えない環境を想定しています。 以上宜しくお願いします。 tomcat5.0 jdk.1.4.2 を使用

    • ベストアンサー
    • Java
  • Ruby 暗号化したファイルの復号について

    Rubyでファイルを暗号化し、それを復号したいのですがうまくいかないため、 質問させていただきます。 Ruby 1.9.3を使用しています。 ・ファイルの暗号化 encrypt.rb ------------------------------------------------- # encoding: cp932 require 'openssl' def encrypt(file, pass)   enc = OpenSSL::Cipher::AES256.new('CBC')   enc.encrypt   enc.pkcs5_keyivgen(pass)   File.open(file, 'rb') do |fin|     File.open("#{file}.sec", 'wb') do |fout|       while buff = fin.read(8000)         fout.write(enc.update(buff))       end       fout.write(enc.final)     end   end   enc.reset end if $*.length > 0   print 'password: '   pass = $stdin.gets.chomp   $*.each do |arg|     begin       encrypt(arg, pass)       puts "#{arg}を暗号化したファイル#{arg}.secを作りました。"     rescue       puts "#{arg}の暗号化に失敗しました。"     end   end   0.upto(pass.length - 1) do |i|     pass[i] = '\xff'   end end ------------------------------------------------- ・ファイルの復号 decrypt.rb ------------------------------------------------- # encoding: cp932 def decrypt(file, pass)   dec = OpenSSL::Cipher::AES256.new('CBC')   dec.decrypt   dec.pkcs5_keyivgen(pass)   File.open(file, 'rb') do |fin|     File.open("#{file}.plain", 'wb') do |fout|       while buff = fin.read(512)         fout.write(dec.update(buff))       end       fout.write(dec.final)     end   end   dec.reset end if $*.length > 0   print 'password: '   pass = $stdin.gets.chomp   $*.each do |arg|     begin       decrypt(arg, pass)       puts "#{arg}を復号したファイル#{arg}.plainを作りました。"     rescue       puts "#{arg}の復号に失敗しました。"     end   end   0.upto(pass.length - 1) do |i|     pass[i] = '\xff'   end end ------------------------------------------------- コマンドプロンプトでencrypt.rb自身を暗号化し、encrypt.rb.secの作成はできるのですが、 decrypt.rbを実行してパスワードを入力しても復号ができません。 どのようにすれば復号できるのか教えていただけますでしょうか。

    • ベストアンサー
    • Ruby
  • 暗号化されない

    MySQLとPHP4でカード番号を暗号化しようとしています。16桁の数値で暗号化が一文字となっていたり復号化できていないようです。教えてください。 暗号化 UPDATE kaiin SET vmem_card_no= aes_encrypt('1111-1111-1111-1111','happy') where vmem_no=9; $result = mysql_query($sql,$db) or die("失敗しました"); 復号化 SELECT AES_DECRYPT(card_no,'happy') FROM kaiin where kaiin_no =9; $result = mysql_query($sql,$db) or die("失敗しました"); if($row = mysql_fetch_array($result,MYSQL_ASSOC)){  print "card_no=".$row['card_no']."<hr>"; }どこかおかしいでしょうか?教えてください。

    • ベストアンサー
    • MySQL
  • C#でAES暗号

    FreeBSDのコマンドとC#で暗号化した結果が異なります。 何が原因なのでしょうか。 コマンド: echo -n '1' | openssl enc -e -aes-128-cbc -K 1111111111111111 -iv 1111111111111111 -base64 結果>jrSCkCNzo9d4sXlRt5lQ/A== C#: http://programmers.high-way.info/cs/aes.html ここのをキーとIVを変更してます 結果>2OnHWXi3UZDpjnZ6Pex4PQ== 以上です。 宜しくお願いします。

  • AES暗号方式について

    AES暗号化方式では,秘密鍵(共通鍵)を用いてランダムに生成したセッション鍵で暗号化し,さらにそのセッション鍵を暗号化する. 復号化する場合は,逆の手順で平文に戻す と認識しています. これを踏まえて以下の質問に回答いただけると幸いです. 1.上の認識は間違っていないでしょうか? 2.暗号文を復号するには,暗号化時に生成したセッション鍵の値と秘密鍵が必要であると言えますか? 3.秘密鍵が漏れなければセッション鍵が漏れても問題ありませんか? 以上,3点についてご教授いただけると幸いです. よろしくお願いします.

  • aes_decryptでsyntax error

    はじめまして。 mysql 4.0.26でaes_decryptを使うとsyntax errorとなってしまいます。(mysql4.0.26+phpMyAdmin 2.6.4-pl2) aes_decryptに関してはこのサイト及びGoogleで調べていろいろ試したのですが実行することができませんでした。 皆様のお知恵を拝借したく質問を作成させていただきました。 ご教授の程よろしくお願いいたします。 -- 実行したソース -- select col1, aes_decrypt(col2, 'key') as col2 from tbl; -- エラーメッセージ -- #1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '( col2 , 'key' ) as col2 from tbl LIMIT 0, 30' at line 1 以下のソースを実行するとエラーが発生することなく終了しますが、 最後のdrop table文を削除すると上記のエラーが発生します。 --- 以下ソース --- create table tbl( col1 integer, col2 tinyblob ); insert into tbl(col1, col2) values (1, aes_encrypt('test','key')); select col1, aes_decrypt(col2, 'key') as col2 from tbl; drop table tbl; --- 上記ソースを実行したときのphpmyadminのメッセージです -- SQL 照会が正常に実行されました 実行した SQL 照会: CREATE TABLE tbl( col1 integer, col2 tinyblob );# MySQLが空の値を返しました。(例えば行が空とか). INSERT INTO tbl( col1, col2 ) VALUES ( 1, aes_encrypt( 'test', 'key' ) ) ;# 影響された行数:1 SELECT col1, aes_decrypt( col2, 'key' ) AS col2 FROM tbl;# 行: 1 DROP TABLE tbl;# MySQLが空の値を返しました。(例えば行が空とか). --

  • 暗号化(perl)→復号化(php)

    暗号化キーを使用した暗号化→復号化で cgi(perl)で暗号化し、phpで復号化を行おうとしております。 AES暗号を使用したのですが、いろいろ設定を変えて 試みたのですが、うまくいきませんでした。 他に暗号化キーを使用した暗号化の方法がありましたら 教えてください。 暗号化(perl)→復号化(php)で実績のあるモジュールが あれば非常に助かります。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • カラムの暗号化

    MySQL4で暗号化を試みています。PHP4と組み合わせです。 他のテーブルでKEYを取り出してそのKEYを用いて暗号化したいです。 update文中で $sql.= " vmem_card_no= '". AES_ENCRYPT(trim($line[108]),$key). "',"; としています。どこかおかしいでしょうか?

    • ベストアンサー
    • MySQL
  • AES_ENCRYPTとLIKE演算子の利用

    AES_ENCRYPTされた文字列の曖昧検索をしたいと思っています。AES_ENCRYPTで暗号化した文字列をBLOB型のフィールドに書き込んでいますが、SELECT文で文字列を抽出時、完全に一致する文字列しか抽出できません。 テーブル名: member フィールド名: id blob name blob email blob テーブルに登録されている文字列: id name email ---------------------------------------- 0001, dokumori, dm@example.com 0002, blahblah, blah@example.com 0003, dokublah, db@example.com (上記は全てAES_ENCRYPTされているものとします) そして、以下のコマンドを走らせても、該当が見つかりません: SELECT * FROM member WHERE name LIKE AES_ENCRYPT ('%doku%','password'); 以下のようにすると、当然ですが、該当するレコードは表示されます: SELECT * FROM member WHERE name = AES_ENCRYPT ('dokumori','password'); AES_ENCRYPTに関しては、文献自体が少ないようで、なかなか答えが見つかりません。この件に関してもしご存じでしたらアドバイスをお願いします。

  • Java(AES)多重の暗号化・復号化、安全?

    メンタル・ポーカー・アルゴリズム↓をJavaで実装したくて http://en.wikipedia.org/wiki/Mental_poker まず、暗号化について調べました。 AESという暗号化の方法を使ってみたのですが、 これなら、多重に暗号化したとして、順番に関わらず、 復号化できるようなので、メンタル・ポーカー・アルゴリズムが実装できると思いました。 しかしながら、私はこのAESという暗号化の方法について、詳しく知りません。 この暗号化方法は、安全なのでしょうか。たとえば、カギがなくとも、暗号前のデータの見当がつく かのようなことが、スーパーコンピュータの手にかかれば一時間もあれば分かってしまう、 というようなことはないでしょうか。 下記は、ランダムな順番で暗号化・復号化してみたコードです↓ 参考になればと思い乗せてみます static void shuffle(int[] array) { for (int i = 1; i < array.length; i++) { int n = random.nextInt(i + 1); int t = array[i]; array[i] = array[n]; array[n] = t; } } public void testAES() throws Exception { String alg = "AES"; byte[] orgData = "abcdefghhijklmno".getBytes(); KeyGenerator keygen = KeyGenerator.getInstance(alg); int keyCount = 16; Key[] keys = new Key[keyCount]; int[] encryptOrder = new int[keyCount]; int[] decryptOrder = new int[keyCount]; for (int i = 0; i < keyCount; i++) { keys[i] = keygen.generateKey(); encryptOrder[i] = i; decryptOrder[i] = i; } shuffle(encryptOrder); shuffle(decryptOrder); byte[][] ivs = new byte[keyCount][]; Cipher cipher = Cipher.getInstance(alg + "/OFB/NoPadding"); byte[] data = orgData.clone(); for (int i = 0; i < keyCount; i++) { int idx = encryptOrder[i]; cipher.init(Cipher.ENCRYPT_MODE, keys[idx]); ivs[idx] = cipher.getIV(); data = cipher.doFinal(data.clone()); } for (int i = 0; i < keyCount; i++) { int idx = decryptOrder[i]; cipher.init(Cipher.DECRYPT_MODE, keys[idx], new IvParameterSpec(ivs[idx])); data = cipher.doFinal(data); } assertTrue(new String(data), Arrays.equals(orgData, data)); }

    • ベストアンサー
    • Java

専門家に質問してみよう