by M.S. » 2008年3月23日(日) 16:18
返信遅くなってしまい、申し訳ありません。
> 「"Crypt" の初期化」とは、第264章に書いてある内容のことを仰っているのでしょうか?
そのとおりです。
> ということは、他に考えられる点は
>
> 1) API関数の宣言
>
> よく見ると *HCTYPTKEYの*が抜けていた箇所がいくつかあったので修正。
>
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Declare Function CryptAcquireContext Lib "advapi32" Alias "CryptAcquireContextA" (phProv As *HCRYPTPROV, pszContainer As BytePtr, pszProvider As BytePtr, dwProvType As DWord, dwFlags As DWord) As BOOL
> Declare Function CryptDestroyKey Lib "advapi32" (hKey As HCRYPTKEY) As BOOL
> Declare Function CryptEncrypt Lib "advapi32" (hKey As HCRYPTKEY, hHash As HCRYPTHASH, Final As Long, dwFlags As DWord, pbData As BytePtr, pdwDataLen As *DWord, dwBufLen As DWord) As BOOL
> Declare Function CryptExportKey Lib "advapi32" (hKey As HCRYPTKEY, hExpKey As HCRYPTKEY, dwBlobType As DWord, dwFlags As DWord, pbData As BytePtr, pdwbDataLen As *DWord) As BOOL
> Declare Function CryptGenKey Lib "advapi32" (hProv As HCRYPTPROV, algid As ALG_ID, dwFlags As DWord, phKey As *HCRYPTKEY) As BOOL
> Declare Function CryptGetUserKey Lib "advapi32" (hProv As HCRYPTPROV, dwKeySpec As DWord, phUserKey As *HCRYPTKEY) As BOOL
> Declare Function CryptReleaseContext Lib "advapi32" (hProv As HCRYPTPROV, dwFlags As DWord) As BOOL
>
> 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 は大丈夫だと思います。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
#Ifdef UNICODE
Const _FuncName_CryptAcquireContext = "CryptAcquireContextW"
#Else
Const _FuncName_CryptAcquireContext = "CryptAcquireContextA"
#endIf
Declare Function CryptAcquireContext Lib "advapi32" Alias _FuncName_CryptAcquireContext (phProv As *HCRYPTPROV, pszContainer As BytePtr, pszProvider As BytePtr, dwProvType As DWord, dwFlags As DWord) As BOOL
をやりたかったので(^^;)
> あとは構造体ofnにデータを格納した後に
>
コード: 全て選択
If GetOpenFileName(ofn)=FALSE Then
> Exit Function
> End If
> これがないとファイル名が取れませんので…
>
初めに載せたコードには誤りがあるので、
現在の修正済みのコードを載せます。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Function Export Encrypt(hWnd As HWND, Temp As BytePtr, Out As BytePtr) As BOOL
Dim hOrg As HANDLE, hAfter As HANDLE
Dim pbBuf[ELM(4096)] As Byte
Dim bEnd = FALSE As Long
Dim hCryptprov As HCRYPTPROV
Dim hExKey As HCRYPTKEY, hKey As HCRYPTKEY
Dim dwByte As DWord, dwResult As DWord
Dim ofn As OPENFILENAME
FillMemory(VarPtr(ofn),Len(ofn),0)
ofn.lStructSize = Len(ofn)
ofn.lpstrFile = Temp
ofn.nMaxFile = MAX_PATH
ofn.Flags = OFN_FILEMUSTEXIST or OFN_HIDEREADONLY
If CryptAcquireContext(VarPtr(hCryptprov), NULL, NULL, PROV_RSA_FULL, 0) = FALSE Then
MessageBox(NULL, "CryptAcquireContext Error", "Error", MB_OK)
Return FALSE
End If
If CryptGetUserKey(hCryptprov, AT_KEYEXCHANGE, VarPtr(hExKey)) = FALSE Then
MessageBox(NULL, "CryptGetUserKey Error", "Error", MB_OK)
Return FALSE
End If
If CryptGenKey(hCryptprov, CALG_RC2, CRYPT_EXPORTABLE, VarPtr(hKey)) = FALSE Then
MessageBox(NULL, "CryptGenKey Error", "Error", MB_OK)
Return FALSE
End If
CryptExportKey(hKey, hExKey, SIMPLEBLOB, 0, NULL, VarPtr(dwByte))
If CryptExportKey(hKey, hExKey, SIMPLEBLOB, 0, pbBuf, VarPtr(dwByte)) = FALSE Then
MessageBox(NULL, "CryptExportKey Error", "Error", MB_OK)
Return FALSE
End If
hOrg = CreateFile(Temp, GENERIC_READ, FILE_SHARE_READ, ByVal NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
hAfter = CreateFile(Out, GENERIC_WRITE, FILE_SHARE_READ, ByVal NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
WriteFile(hAfter, VarPtr(dwByte), Len(dwByte), VarPtr(dwResult), ByVal NULL)
WriteFile(hAfter, pbBuf, Len(dwByte), Varptr(dwResult), ByVal NULL)
While 1
ReadFile(hOrg, pbBuf, Len(pbBuf), VarPtr(dwByte), ByVal NULL)
If dwByte < Len(pbBuf) Then
bEnd = TRUE
End If
CryptEncrypt(hKey, 0, bEnd, 0, pbBuf, VarPtr(dwByte), Len(pbBuf))
WriteFile(hAfter, pbBuf, Len(dwByte), VarPtr(dwResult), ByVal NULL)
If bEnd Then
Exit While
End If
Wend
CryptDestroyKey(hKey)
CryptDestroyKey(hExKey)
CryptReleaseContext(hCryptprov, 0)
CloseHandle(hOrg)
CloseHandle(hAfter)
Return TRUE
End Function
> ※CryptAcquireContextは成功しましたが、今度はCryptGetUserKeyでGetLastError()がNTE_NO_KEYを返して失敗したので、例の「初期化」がうまくいっていれば動くような気がします。なお、こちらで使用したのはActiveBasic4.24です。
エラーは無くなったのですが、
超肥大化したファイルが出力されてしまいます。
どうしてでしょうか…?
返信遅くなってしまい、申し訳ありません。
> 「"Crypt" の初期化」とは、第264章に書いてある内容のことを仰っているのでしょうか?
そのとおりです。
> ということは、他に考えられる点は
>
> 1) API関数の宣言
>
> よく見ると *HCTYPTKEYの*が抜けていた箇所がいくつかあったので修正。
> [hide][code]Declare Function CryptAcquireContext Lib "advapi32" Alias "CryptAcquireContextA" (phProv As *HCRYPTPROV, pszContainer As BytePtr, pszProvider As BytePtr, dwProvType As DWord, dwFlags As DWord) As BOOL
> Declare Function CryptDestroyKey Lib "advapi32" (hKey As HCRYPTKEY) As BOOL
> Declare Function CryptEncrypt Lib "advapi32" (hKey As HCRYPTKEY, hHash As HCRYPTHASH, Final As Long, dwFlags As DWord, pbData As BytePtr, pdwDataLen As *DWord, dwBufLen As DWord) As BOOL
> Declare Function CryptExportKey Lib "advapi32" (hKey As HCRYPTKEY, hExpKey As HCRYPTKEY, dwBlobType As DWord, dwFlags As DWord, pbData As BytePtr, pdwbDataLen As *DWord) As BOOL
> Declare Function CryptGenKey Lib "advapi32" (hProv As HCRYPTPROV, algid As ALG_ID, dwFlags As DWord, phKey As *HCRYPTKEY) As BOOL
> Declare Function CryptGetUserKey Lib "advapi32" (hProv As HCRYPTPROV, dwKeySpec As DWord, phUserKey As *HCRYPTKEY) As BOOL
> Declare Function CryptReleaseContext Lib "advapi32" (hProv As HCRYPTPROV, dwFlags As DWord) As BOOL[/code][/hide]
>
> 2) TRUEの意味合い
> MSDNによると、暗号化APIの戻り値は成功したら「0以外」とあるので、「<>TRUE」とすると予期せぬ結果になるかもしれません(ならないかもしれません)。
> ActiveBasicでのTRUEは定数の「1」ですので、「<>TRUE」すなわち「1以外」と、失敗を表す「FALSE(0)である」は必ずしも同値とは限りません。「<>TRUE」の代わりに「=FALSE」にしてみるとよいかもしれません。
>
> 3) Return
> ActiveBasicのバージョンによっては、ReturnはC言語でいうreturnと違う意味を表します。
> C言語でいう return xxx; と同様の表現としては
> [code](関数名)=xxx
> Exit Function[/code]
> というのが考えられます。
>
AB5 CP4 でやったので、
return は大丈夫だと思います。
[hide][code]#Ifdef UNICODE
Const _FuncName_CryptAcquireContext = "CryptAcquireContextW"
#Else
Const _FuncName_CryptAcquireContext = "CryptAcquireContextA"
#endIf
Declare Function CryptAcquireContext Lib "advapi32" Alias _FuncName_CryptAcquireContext (phProv As *HCRYPTPROV, pszContainer As BytePtr, pszProvider As BytePtr, dwProvType As DWord, dwFlags As DWord) As BOOL[/code][/hide]をやりたかったので(^^;)
> あとは構造体ofnにデータを格納した後に
> [code]If GetOpenFileName(ofn)=FALSE Then
> Exit Function
> End If[/code]
> これがないとファイル名が取れませんので…
>
初めに載せたコードには誤りがあるので、
現在の修正済みのコードを載せます。
[hide][code]Function Export Encrypt(hWnd As HWND, Temp As BytePtr, Out As BytePtr) As BOOL
Dim hOrg As HANDLE, hAfter As HANDLE
Dim pbBuf[ELM(4096)] As Byte
Dim bEnd = FALSE As Long
Dim hCryptprov As HCRYPTPROV
Dim hExKey As HCRYPTKEY, hKey As HCRYPTKEY
Dim dwByte As DWord, dwResult As DWord
Dim ofn As OPENFILENAME
FillMemory(VarPtr(ofn),Len(ofn),0)
ofn.lStructSize = Len(ofn)
ofn.lpstrFile = Temp
ofn.nMaxFile = MAX_PATH
ofn.Flags = OFN_FILEMUSTEXIST or OFN_HIDEREADONLY
If CryptAcquireContext(VarPtr(hCryptprov), NULL, NULL, PROV_RSA_FULL, 0) = FALSE Then
MessageBox(NULL, "CryptAcquireContext Error", "Error", MB_OK)
Return FALSE
End If
If CryptGetUserKey(hCryptprov, AT_KEYEXCHANGE, VarPtr(hExKey)) = FALSE Then
MessageBox(NULL, "CryptGetUserKey Error", "Error", MB_OK)
Return FALSE
End If
If CryptGenKey(hCryptprov, CALG_RC2, CRYPT_EXPORTABLE, VarPtr(hKey)) = FALSE Then
MessageBox(NULL, "CryptGenKey Error", "Error", MB_OK)
Return FALSE
End If
CryptExportKey(hKey, hExKey, SIMPLEBLOB, 0, NULL, VarPtr(dwByte))
If CryptExportKey(hKey, hExKey, SIMPLEBLOB, 0, pbBuf, VarPtr(dwByte)) = FALSE Then
MessageBox(NULL, "CryptExportKey Error", "Error", MB_OK)
Return FALSE
End If
hOrg = CreateFile(Temp, GENERIC_READ, FILE_SHARE_READ, ByVal NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
hAfter = CreateFile(Out, GENERIC_WRITE, FILE_SHARE_READ, ByVal NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
WriteFile(hAfter, VarPtr(dwByte), Len(dwByte), VarPtr(dwResult), ByVal NULL)
WriteFile(hAfter, pbBuf, Len(dwByte), Varptr(dwResult), ByVal NULL)
While 1
ReadFile(hOrg, pbBuf, Len(pbBuf), VarPtr(dwByte), ByVal NULL)
If dwByte < Len(pbBuf) Then
bEnd = TRUE
End If
CryptEncrypt(hKey, 0, bEnd, 0, pbBuf, VarPtr(dwByte), Len(pbBuf))
WriteFile(hAfter, pbBuf, Len(dwByte), VarPtr(dwResult), ByVal NULL)
If bEnd Then
Exit While
End If
Wend
CryptDestroyKey(hKey)
CryptDestroyKey(hExKey)
CryptReleaseContext(hCryptprov, 0)
CloseHandle(hOrg)
CloseHandle(hAfter)
Return TRUE
End Function[/code][/hide]
> ※CryptAcquireContextは成功しましたが、今度はCryptGetUserKeyでGetLastError()がNTE_NO_KEYを返して失敗したので、例の「初期化」がうまくいっていれば動くような気がします。なお、こちらで使用したのはActiveBasic4.24です。
エラーは無くなったのですが、
超肥大化したファイルが出力されてしまいます。
どうしてでしょうか…?