ファイルの暗号化

返信する


答えを正確に入力してください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: ファイルの暗号化

by M.S. » 2008年4月07日(月) 23:44

今、Virtual PC 上の WinME で、
BCC で新たにビルドした同じ DLL 及び初期化を実行すると、
正常に暗号化できました。
恐らく、初期化に失敗したのだと思います。
この初期化を元に戻す方法はないのでしょうか?

by M.S. » 2008年3月29日(土) 19:35

> 「第264章 暗号化の前準備」のプログラムは実行してますよね?
>
はい、既にやってあります。


> あと、最新のソースを載せてもらえると原因が特定しやすいです。
> (「編集」で↑を毎回更新するといいかと)

初めに載せたコードを現在のものに更新しておきました。

by のぶあや » 2008年3月28日(金) 22:17

「第264章 暗号化の前準備」のプログラムは実行してますよね?

あと、最新のソースを載せてもらえると原因が特定しやすいです。
(「編集」で↑を毎回更新するといいかと)

by M.S. » 2008年3月26日(水) 23:24

のぶあやさん、わざわざ調べていただきありがとうございます。m(_ _)m
DLL の方はビルドできるようになりました。

しかし、その DLL を使用して暗号化をしようとすると、
また「CryptAcquireContext Error」
と出てしまいます。
また、その DLL を使用するプログラムを新たにデバッグビルド、
ビルドをするとコンパイラがエラーで落ちてしまいます。
DLL がまだダメなんでしょうか?
よくわからないのですが…

by のぶあや » 2008年3月24日(月) 23:23

cのsizeof演算子の注意点 なので、while直後のReadFileは

コード: 全て選択

c言語の場合
ReadFile(hOrg, pbBuf, sizeof(pbBuf), &dwByte, NULL);

ABの場合
Dim pbBuf[ELM(4096)] As Byte (と宣言されているのであれば)
ReadFile(hOrg, pbBuf, SizeOf(Byte)*4096, VarPtr(dwByte), ByVal NULL);
あと、その直後の

コード: 全て選択

c言語
CryptEncrypt(hKey, 0, bEnd, 0, pbBuf, &dwByte, sizeof(pbBuf));
WriteFile(hAfter, pbBuf, dwByte, &dwResult, NULL);

AB(以下の2行は間違っています)
CryptEncrypt(hKey, 0, bEnd, 0, pbBuf, VarPtr(dwByte), Len(pbBuf))
WriteFile(hAfter, pbBuf, Len(dwByte), VarPtr(dwResult), ByVal NULL)
おそらくですが、
CryptEncrypt関数の第5引数に処理するデータ、第7引数にそのサイズを指定し、第6引数に結果のデータサイズが格納されると思われます。
なので、ここの第7引数もSizeOf(Byte)*4096としなければなりません。
またここでdwByteに処理後のデータ長が格納されると思うので、
WriteFileの第3引数はLen(dwByte)ではなく、dwByteになります。

<追記>
調べたらLen関数に配列を指定した場合、cの場合と同じになりました;;;
上記のSizeOf云々は忘れてください。

by M.S. » 2008年3月24日(月) 15:27

>

コード: 全て選択

WriteFile(hAfter, pbBuf, dwByte, &dwResult, NULL);
となってるので、
> 第三引数はLen(dwByte)ではなくdwByteだと思うのですが・・・。
>
> BasicのLen(a)とCのsizeof(a)が大体同じだったと思います。


Len を外してビルドしてみましたが、
コンパイラが落ちてビルドできませんでした…。
デバッグビルドはできるのですが…

by konisi » 2008年3月23日(日) 22:46

コード: 全て選択

WriteFile(hAfter, pbBuf, dwByte, &dwResult, NULL);
となってるので、
第三引数はLen(dwByte)ではなくdwByteだと思うのですが・・・。

BasicのLen(a)とCのsizeof(a)が大体同じだったと思います。

by M.S. » 2008年3月23日(日) 20:41

> よく読んでないのですが、Whileループ内とその直前の二つの

コード: 全て選択

WriteFile(hAfter, pbBuf, Len(dwByte), VarPtr(dwResult), ByVal NULL)
の第三引数が間違っているように見えてならないのですが、どうなんでしょう?
C のコードがこうなので、
C をよく理解していない僕には合っているようにしか見えないのですが…

// VC++ 2008 Express Edition で同じ DLL を作ってみましたが、
// 文字列かファイル操作がうまくいっていないのでわかりませんが、
// 一応ちゃんと元ファイルより小さくなりました。

by konisi » 2008年3月23日(日) 17:24

よく読んでないのですが、Whileループ内とその直前の二つの

コード: 全て選択

WriteFile(hAfter, pbBuf, Len(dwByte), VarPtr(dwResult), ByVal NULL)
の第三引数が間違っているように見えてならないのですが、どうなんでしょう?

by M.S. » 2008年3月23日(日) 16:18

返信遅くなってしまい、申し訳ありません。


> 「"Crypt" の初期化」とは、第264章に書いてある内容のことを仰っているのでしょうか?

そのとおりです。

> ということは、他に考えられる点は
>
> 1) API関数の宣言
>
> よく見ると *HCTYPTKEYの*が抜けていた箇所がいくつかあったので修正。
> >
> 2) TRUEの意味合い
> MSDNによると、暗号化APIの戻り値は成功したら「0以外」とあるので、「<>TRUE」とすると予期せぬ結果になるかもしれません(ならないかもしれません)。
> ActiveBasicでのTRUEは定数の「1」ですので、「<>TRUE」すなわち「1以外」と、失敗を表す「FALSE(0)である」は必ずしも同値とは限りません。「<>TRUE」の代わりに「=FALSE」にしてみるとよいかもしれません。
>
> 3) Return
> ActiveBasicのバージョンによっては、ReturnはC言語でいうreturnと違う意味を表します。
> C言語でいう return xxx; と同様の表現としては
>

コード: 全て選択

(関数名)=xxx
> Exit Function
> というのが考えられます。
>

AB5 CP4 でやったので、
return は大丈夫だと思います。 をやりたかったので(^^;)

> あとは構造体ofnにデータを格納した後に
>

コード: 全て選択

If GetOpenFileName(ofn)=FALSE Then
> 	Exit Function
> End If
> これがないとファイル名が取れませんので…
>

初めに載せたコードには誤りがあるので、
現在の修正済みのコードを載せます。
> ※CryptAcquireContextは成功しましたが、今度はCryptGetUserKeyでGetLastError()がNTE_NO_KEYを返して失敗したので、例の「初期化」がうまくいっていれば動くような気がします。なお、こちらで使用したのはActiveBasic4.24です。

エラーは無くなったのですが、
超肥大化したファイルが出力されてしまいます。
どうしてでしょうか…?

by hira » 2008年3月12日(水) 23:28

「"Crypt" の初期化」とは、第264章に書いてある内容のことを仰っているのでしょうか?
ということは、他に考えられる点は

1) API関数の宣言

よく見ると *HCTYPTKEYの*が抜けていた箇所がいくつかあったので修正。 2) TRUEの意味合い
MSDNによると、暗号化APIの戻り値は成功したら「0以外」とあるので、「<>TRUE」とすると予期せぬ結果になるかもしれません(ならないかもしれません)。
ActiveBasicでのTRUEは定数の「1」ですので、「<>TRUE」すなわち「1以外」と、失敗を表す「FALSE(0)である」は必ずしも同値とは限りません。「<>TRUE」の代わりに「=FALSE」にしてみるとよいかもしれません。

3) Return
ActiveBasicのバージョンによっては、ReturnはC言語でいうreturnと違う意味を表します。
C言語でいう return xxx; と同様の表現としては

コード: 全て選択

(関数名)=xxx
Exit Function
というのが考えられます。

あとは構造体ofnにデータを格納した後に

コード: 全て選択

If GetOpenFileName(ofn)=FALSE Then
	Exit Function
End If
これがないとファイル名が取れませんので…

※CryptAcquireContextは成功しましたが、今度はCryptGetUserKeyでGetLastError()がNTE_NO_KEYを返して失敗したので、例の「初期化」がうまくいっていれば動くような気がします。なお、こちらで使用したのはActiveBasic4.24です。

by M.S. » 2008年3月11日(火) 00:28

作った DLL で暗号化しようとすると、
「CryptAcquireContext Error」
と出てしまいます。
一度だけエラーが出ずに暗号化を終了したのですが、
それ以降ずっと出てしまいます。
既に "Crypt" の初期化はしてあります。
どうして "CryptAcquireContext" で失敗してしまうのでしょうか?

Re: ファイルの暗号化

by M.S. » 2008年3月10日(月) 00:16

> WriteFile(hAfter, VarPtr(dwByte), Len(dwByte), VarPtr(dwResult), ByVal NULL)
>
> ReadFile(hOrg, pbBuf, Len(pbBuf), VarPtr(dwByte), ByVal NULL)
>
> といった感じでしょうか。
> 後は細かいですが、C言語で指定する配列の要素数と、ActiveBasicで指定する配列の要素数は意味合いが違います。
> C言語で
>
> int a[10];
>
> と書くと添え字は0~9で要素は10個ですが、これをActiveBasicに移植するときに
>
> Dim a[10] As Long
>
> と書くと0~10の11個になります。正しい書き換えは
>
> Dim a[9] As Long
>
> となりますが、要素数が10であることを表明する(というよりC言語風の)書き方として
>
> Dim a[ELM(10)] As Long
>
> とすることもできます。
> 投稿されたコードなら
>
> Dim pbBuf[ELM(4096)] As Byte
>
> など。要素数が少なすぎるわけではないので、実害は少ないかもしれませんが、構造体のサイズになるとアドレスがずれてくるので不具合の原因になったりします。
>

配列は気をつけないといけないのですね
今まで気にしたことがありませんでしたが、
不具合の原因になったりするんですね・・・。

> それから…ハンドル型(HCRYPTPROVなど、Hで始まる型)をTypeDefするときは元のデータ型をLongではなくHANDLEにしておいたほうがよいかと思われます。今は問題ないですが、将来64ビット化したときにはハンドルやポインタはInt64に相当するサイズ(64ビット)になるので、そのときに問題が起こるのでしょう。
>

全く気にしていませんでしたというか、
ハンドル型であることに気づいていませんでした。(^^;)
ありがとうございます。

> 色々細かく書いてしまいました。m(_ _)m

解りやすくてよかったです、
ありがとうございます。

移植するときはいつも hira さんのサイトの、
逆引きリファレンス を参考にやっていますが、
やっぱり C を解っていないとダメですね(^^;)

色々解説していただき、ありがとうございました。m(_ _)m

Re: ファイルの暗号化

by hira » 2008年3月09日(日) 23:35

WriteFile(hAfter, VarPtr(dwByte), Len(dwByte), VarPtr(dwResult), ByVal NULL)

ReadFile(hOrg, pbBuf, Len(pbBuf), VarPtr(dwByte), ByVal NULL)

といった感じでしょうか。
後は細かいですが、C言語で指定する配列の要素数と、ActiveBasicで指定する配列の要素数は意味合いが違います。
C言語で

int a[10];

と書くと添え字は0~9で要素は10個ですが、これをActiveBasicに移植するときに

Dim a[10] As Long

と書くと0~10の11個になります。正しい書き換えは

Dim a[9] As Long

となりますが、要素数が10であることを表明する(というよりC言語風の)書き方として

Dim a[ELM(10)] As Long

とすることもできます。
投稿されたコードなら

Dim pbBuf[ELM(4096)] As Byte

など。要素数が少なすぎるわけではないので、実害は少ないかもしれませんが、構造体のサイズになるとアドレスがずれてくるので不具合の原因になったりします。

それから…ハンドル型(HCRYPTPROVなど、Hで始まる型)をTypeDefするときは元のデータ型をLongではなくHANDLEにしておいたほうがよいかと思われます。今は問題ないですが、将来64ビット化したときにはハンドルやポインタはInt64に相当するサイズ(64ビット)になるので、そのときに問題が起こるのでしょう。

色々細かく書いてしまいました。m(_ _)m

Re: ファイルの暗号化

by M.S. » 2008年3月09日(日) 23:13

> C言語とは違い、SizeOf関数の引数にできるのは、データ型のみです(例えば SizeOf(Long) のように使います)。
> 変数のサイズを取得する場合はLen関数を使います。
> すなわち
> If dwByte < SizeOf(pbBuf) Then
> ↓
> If dwByte < Len(pbBuf) Then
> となります(SizeOf(pbBuf) の記述がもう1箇所ありますが、そちらも同様です)。

エラーが出た部分を "Len" に書き換えてもなっていたので、
何故エラーが無くならないのかと思っていましたが、
もうひとつ "sizeof" になっているところがあったのに気付いていませんでした。
多分言われなければ全然気づかず放置していたと思います。
hira さん、ありがとうございました!

載せたコードですが、
元の C のコードを見て(厳密にはコピペして AB 用に修正)しましたが、
C をよく理解していないため間違っているかもしれないので、
そちらの方もどなたか見ていただけるとありがたいです。
(特に ReadFile, WriteFile のあたりを中心に…)

ページトップ