68user's page 掲示板

Prev< No. 3708〜3713> Next  [最新発言に戻る] [過去ログ一覧]
No. 3708 # Sjr 2004/05/05 (水) 20:19:41
DESについて質問させて下さい。
OpensslコマンドでDESを使っているのですが、間違った鍵で復号しようとすると
bad decryptというエラーがでます。パリティチェックはOKとします。
これはDESの仕様上、エラーが検出できるということなのでしょうか?
DESというと単にビット単位の置換だと思っているので、エラーが検出できるのが
ちょっと不思議です。
TripleDESの中ででも、いきなり関係無い鍵で復号したりしてますから、さらに
不思議です。

なにか根本的に理解が違っている気もするので、宜しければご教授ください。

No. 3709 # 68user 2004/05/05 (水) 22:59:32
>>3708 Sjr
`bad decrypt' を出しているのは多分 rypto/evp/evp_enc.c の

    int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl){
          b=ctx->cipher->block_size;
          n=ctx->final[b-1];
          if (n > b){
                EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);

だと思います。PKCS#5 で定義されている操作に矛盾が発生すると
このエラーが発生すると思っています。

ところで PKCS#5 の日本語訳のありかをご存知の方いらっしゃい
ませんか? (解説している書籍でも可) 以前自分で訳してみたものの、
よく理解していないため何が何だかわからない日本語ができあがって
しまいました。

No. 3710 # Sjr 2004/05/06 (木) 10:56:55
68userさん、ご回答有難うございました。
恥ずかしながらPKCSというのは知りませんでした。PKCS#5というのは、
簡単に言うと文字列を鍵とする場合の決まりごと、みたいなものでしょうか?
頂いたソースやPKCS#5を斜め読みしてもまだ今一つピンときていません。
勉強したいと思います。

今のところなんとなく、PKCS#5でのPS(Padding String)についての記述を
見て、Padding ruleによってはエラーが検出できるのではと予想しています。

やっぱりアルゴリズムを見ていくしかないですねぇ…

No. 3711 # 68user 2004/05/06 (木) 11:54:23
>>3710 Sjr
> 簡単に言うと文字列を鍵とする場合の決まりごと、みたいなものでしょうか?
決まりごとというか、RSA が作った決めごとですね。

DES は 64bit のデータを暗号化・復号化する機能しか持っていません
(だから DES は 64bit ブロック暗号)。

これでは 64bit を超えるデータを暗号化できないので、データを分割して
暗号化する方法の一つが CBC モード (FIPS PUB 81 で規定)。一方、データ
列が 64bit に満たない場合のパディング方法などを規定しているのが
PKCS#5 です。

PKCS#5 でのパディングは
      データ1バイトの場合: A -> A 07 07 07 07 07 07 07 としてから暗号化
      データ2バイトの場合: A B -> A B 06 06 06 06 06 06 としてから暗号化
                  :
      データ7バイトの場合: A B C D E F G -> A B C D E F G 01 としてから暗号化
      データ8バイトの場合: A B C D E F G H -> A B C D E F G H 08 08 08 08 08 08 08 08 としてから暗号化
としていますね。

と書いているうちにわかったような気がしますが、
      http://www.jp.freebsd.org/cgi/cvsweb.cgi/src/crypto/openssl/crypto/evp/evp_enc.c?rev=1.1.1.1.2.4
の EVP_DecryptFinal_ex が呼ばれるときの流れは

      残りブロックサイズ = ctx->cipher->block_size;
      if (残りブロックサイズ > 1){
          /* 残りはパディング部分のみ */
          n=ctx->final[b-1]; /* 最後の 1バイトを読む。その値はパディング長であるはず */
          if (n > b)
              /* パディング長が残りブロックサイズを超えているならエラー */
              for (i=0; i<n; i++)
                    パディング部分の値が全て n であることをチェック
          /* ここまできたら、パディング部分が正しいことがわかる */
          n=ctx->cipher->block_size-n; /* パディング部分を除いたブロックサイズを取得 */
          for (i=0; i<n; i++) /* パディング部分より前のデータについて出力バッファに書き出す */
              out[i]=ctx->final[i];

てな感じでしょうか。

No. 3712 # 68user 2004/05/06 (木) 12:05:05
一応補足。

>>3708 Sjr
> DESというと単にビット単位の置換だと思っているので、エラーが検出できるのが
> ちょっと不思議です。
DES 自体は、鍵に含まれるパリティを以外の誤り検出機能はない、という
理解で正しいと思います。

しかし、PKCS#5 においては誤った鍵を使うと
>>3711 68user
> データ1バイトの場合: A -> A 07 07 07 07 07 07 07 としてから暗号化
> データ2バイトの場合: A B -> A B 06 06 06 06 06 06 としてから暗号化
この最後のデータ列 (06 06 06 06 06 06 など) がめちゃくちゃになって
しまうため、パディングチェック時にエラーとなる、ということですね。


なお、PKCS#5 は DES に限らず、ブロック暗号一般に適用できます。ただし
PKCS#5 は 64bit 暗号に特化した書き方がされているので、64bit 超暗号に
一般化したものが PKCS#7 に規定されています。

# と言っても、mod 8 とか書いてあるか、mod k と書いてあるかの違いしか
# ないような気がしますけど。

No. 3713 # Sjr 2004/05/07 (金) 10:09:34
x168userさん、詳細な説明ありがとうございます。
誤りの検出については、ほぼ理解できたと思います。


>データ8バイトの場合: A B C D E F G H -> A B C D E F G H 08 08 08 08 08 08 08 08 としてから暗号化

のところは意外でした。データが増えてしまうのでしょうか。
確かにこうしないとパディングされているのかされていないのかが
分からない、ということなのでしょうけど。
よくよく見ていくと色々と考えられていて面白いですね。

Prev< No. 3708〜3713> Next  [最新発言に戻る] [過去ログ一覧]