★ExcelVBA ~ 【電子帳簿保存法・タイムスタンプがらみ】ファイルのハッシュ値をゲットする関数

※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。

参考
紙でもらった請求書はPDF化しないといけないか?→不要。
PDFやExcelなど、電子データでもらった請求書は紙にしていいか?→紙だけじゃダメ。デジタルデータのほうを保管しないといけない。
結局、「全部紙でちょうだい」が「何もしなくていい」となります。
ただし、せっかくもらった紙を「PDF化してしまう」と、
保存要件の対象になってしまうので、紙でもらったものは必ず紙のみで保管する。

======================

以下、本文です。

電子帳簿保存法の「電子データで交付や受取をした取引のデータ保存の義務化」について、猶予期間が、本年、2023年12月31日に終わります。

年明け・2024年1月1日からは、
「電子データで交付や受取をした取引のデータ保存」が「完全義務化」となります。
「紙に印刷して保存Only」が法的に「ダメ・違法」になります。
(※電子データのままの保存がちゃんとしてあれば、追加で紙に印刷することは違法ではない。万が一のために重要書類だけ電子と紙の両方で保管することは違法ではない。管理が大変になるかもしれませんけど。)

もちろん、その対象は「電子データでもらったもの」「だけ」です。
紙でもらった請求書は紙のままでOKです。PDF化する必要はないし、PDF化すると逆に「法律上の保存システム」が必要になってしまうので、むしろPDF化などをしてはいけません。

で、結局どのような方法が義務付けられるのかというと、結論から言うと、
「社内規約さえ作っておけばいい」
です。

基本的には、「もらったデータ(PDF等)を絶対に編集・改ざんしない」という原則にして、そういった、「取り扱いのルール(=社内規約書)」を書いたものを用意して、「日付、取引先、金額」での検索がすぐにできる状態におけば、巷でよく言われている「有料のタイムスタンプ付加」などは不要のようです。
(ただし、それは請求書や見積書などの書類のみ。「電子契約書」などの場合は別。「電子契約書」などの場合はタイムスタンプなどが必須。)

※参考:国税庁HP ~ 問9 電子取引の取引情報に係る電磁的記録の保存等を行う場合には、どのような要件を満たさなければならないのでしょうか。

以下、要件の引用です。↓

電子計算機処理システムの概要を記載した書類の備付け(自社開発のプログラムを使用する場合に限ります。)(規31三イ、5七、81) →★【自社オリジナルシステムの場合のみ、必須。市販ビジネスソフトの場合等は不要。】保存システム(保存機能)の概要・操作方法など
 見読可能装置の備付け等(規31四、81) →★【必須】パソコンなどのPDF等がよめる機器の準備
 検索機能の確保(規31五、5七、81) →★【必須】「日付、金額、取引先」がすぐに検索できる機能の準備。
 次のいずれかの措置を行う(規81) →★【必須】ただ、「いずれか」なので、「4」だけでもOK。

  1. 一 タイムスタンプが付された後の授受
  2. 二 授受後遅滞なくタイムスタンプを付す
  3. 三 データの訂正削除を行った場合にその記録が残るシステム又は訂正削除ができないシステムを利用
  4. 四 訂正削除の防止に関する事務処理規程の備付け

 

上記の表の、一番下の、「四 訂正削除の防止に関する事務処理規程の備付け」が
前述した、
『基本的には、「もらったデータ(PDF等)を絶対に編集・改ざんしない」という原則にして、そういった、「取り扱いのルール(=社内規約書)」』
ということになります。

ただ、そのとき、「絶対に編集させない」ということを「助ける」意味で、「電帳法が言うところのタイムスタンプ」、「ファイルのハッシュ値と更新日付」を記録しておくのは1つの方法だと思います。
もちろん、Acrobat Readerで無料のタイムスタンプを付ける方法もよいかと思います。

参考:Acrobat Readerで無料のタイムスタンプを付けた場合の証拠?のミニ画面
    ↓

ただし、無料のタイムスタンプは、あくまでも、
電子契約書以外の電子データにて、
「四 訂正削除の防止に関する事務処理規程の備付け」、をする場合の、
「単に、より改ざんを予防するためだけの」、
「補完機能」、
としてでしか使ってはいけません。

「Acrobat Readerで無料でタイムスタンプを付ける方法」はタイムサーバーが国税庁が認めないタイプのサーバーの恐れもあるため、電子契約書には使えないかもしれません。だからです。
なので、もし無料のタイムスタンプを付けるなら、アクロバットではなくて、「みんなのタイムスタンプ」みたいなものが良いのかもしれません。

参考:みんなのタイムスタンプ

Acrobat Readerの無料タイムスタンプだと、結局、あとになって、
「このサーバーのタイムスタンプだと、要件を満たしたことにならないので、ここに保存してあるPDFは全部違法です」、
と言われてしまう恐れがあります。ぞっとしますね(^^)

そうならないようにするために、以下のようなことが必要だと思われます。

(01)電子契約書などの有料のタイムスタンプが必要な書類には、
  しっかり有料のタイムスタンプを付ける。
  無料なら、「みんなのタイムスタンプ」のようなサービス?

(02)電子契約書以外の、タイムスタンプが不要な書類には、
  社内規約で対応し、保険(改ざん予防策)として無料のタイムスタンプか、
  後述のような関数を使って、「ファイルのハッシュ値+更新日付」などの記録、
  保管しておくといいと思います。

今回のプログラムは、上記の(02)に使うためのモノです。
(「みんなのタイムスタンプ」のような「Webに自社の書類をアップすること自体が嫌だ、怖い」、と言う場合も、使えるかもしれません。予防策としてだけ。)

ではこれ以下に、「指定したファイルからハッシュ値を取得する関数のあれこれ」、
をご紹介します。
(日付を付加まではしていませんので、その部分はまた自作する必要があります。)

  
  

●コマンドプロンプトでのハッシュ値の割り出しの実行結果をVBA側に受け取る方式
(※受け取り先が「配列」の方法)

(※コマンドを実行したあと、その結果の「数行」からハッシュ値だけを抽出
  するコードも一緒になっています。SHA256以上でも計算できます。)

これはコマンドプロンプトのコマンドを利用する方法です。
(API利用での方法はこちら→スーの道具箱/気まぐれ日記/2007-03-08

基本、この方式は、主に7、8、10、11、で使えます。
Windows2000SP4Pro(他のバージョン未確認)や、XP、でも使えるかもしれませんが、
未確認です。使えないかもしれません。
後述の「GetFileHashSha1()」関数、「GetFileHashSha1ForWin2000()」関数のほうが簡単かもしれません。

このプログラムはそこそこ速いです。
のちの「APIを使う方法」の2倍は速いです。
「.NetFrameWork3.5」を使う方法よりは若干遅いかも?しれません。
なお、コマンドの実行時に黒い画面がちらつきますので、
それが嫌な方は「.NetFrameWork3.5」を使う方法にしてみてください。

なお、この方法は、Windows2000SP4Pro(他のバージョン未確認)、XPの場合、
「SHA1」しかハッシュ値の計算ができません。
MD5もできるかもしれませんが未確認です。
(7や8は未確認です。Win10、11なら、SHA256以上のハッシュ値計算ができます。)

ただ、「SHA1」は、Googleのどこかのチームが2017年にようやく突破した、
というものですので、一般の会社であればそんな力がある会社は少ないと思いますから、
現実的には「SHA1」で十分、「原本保証」になるかと思います。
「SHA1」以前の、「MD5」というより脆弱性のあるハッシュ計算方式ですら、
「実際の裁判では」「ファイルが改ざんされた」と「証明するほうが困難」…、
だそうです。
下記のURLは、そのことが書かれたWebページですが、
「mhtml形式などでの保存が必須」というくらいの良い内容です。
是非、保存しておいてください。

ITの知識不足による判決間違い?-MD5の脆弱性

基本、XPでは、通常はすぐには使えないかもです。
しかし、
「Windows Server 2003 Service Pack 2 管理ツール パック (x86 エディション用)」
https://www.microsoft.com/ja-jp/download/details.aspx?id=6315
をダウンロード、インストールすると、
動くようになるかも?です。

その際、すべてのPCにそれをインストールしなくてもOKです。
どれか1つのPCにインストールし、その完了後に、最低限必要なファイルを
2つ抜き出して、他のマシンには、それをコピペすればOKです。
(「c:\windows\system32」に。)

その2つのファイルは、
「c:\windows\system32」の、「certutil.exe」と「certadm.dll」です。

2000の場合も似ようなコードでやれます。
(SP4のPro版しか確認取れてません。後述の「GetFileHashSha1ForWin2000()」関数です。)

で、2000SP4のPro版ではその2つのファイルはすでに入っているようですが、
ただし、格納場所(「C:\WINNT\system32\dllcache」)にPATHが
通ってないので機能しません。
機能させるには(「C:\WINNT\system32\dllcache」)にPATHを通して、
余計な同名のファイルをリネームすると、使えることがあるようです。
(PATHを通す方法は後述します。)

ただ、このプログラムはPATHが通っていても、2000系でちゃんと動くかはわかりません。
動くかもしれないし、動かないかもしれません。
はっきりしていますのは、後述の「GetFileHashSha1ForWin2000()」関数のほうなら
確実だということです。

 

  
  

  
●PATHを通すプログラム

後述の「PATH_Add01()」にて、できます。

  

  

●APIを使う方法32bit版(32bit版のExcel、Wordなどのみでしか使えません。)
(※コマンドプロンプト利用の方法ように、受けた結果が複数行にならないです。
  普通の関数と同じく、文字列型のハッシュ値がまんまで返ってきます。)

以下、「スーの道具箱/気まぐれ日記/2007-03-08」が消えちゃうといけないので、メモ引用。

このプログラムは「遅い」ですが、Windows2000SP4ProでもXPsp2などでも使えます。
何の追加のdllやexeなどのファイルが要らないので、「容量が1MB以下の小さなファイルばかり」のときは、これで十分間に合います。

容量が1MB以上のファイル(特に2MB以上のファイル)が増えてきたら、
「certutil.exe」と「certadm.dll」などのファイルを使っての、
「コマンドプロンプトでのハッシュ値割出しの実行結果をVBA側に受け取る方式」
がいいと思います。
(この方式はXPやWin10などで使えますが、実行結果の行数が異なるため、
 それぞれ、 実行結果をVBA側に受け取るときのプログラムを少し
 変える必要があります。)

●APIを使う方法64bit版(64bit版のExcel、Wordなどのみでしか使えません。)
上記のプログラムを64bit版に直したものです。

このプログラムは「遅い」です。
また、64bitなので、XPSp2やWindows2000SP4Proなどのうち32bitのOSでは動きません。

  

  
  

●.NET FrameWork3.5を利用した方法(XP以降?で使える?)
(※コマンドプロンプトもAPIも使わずに、「.NET FrameWork3.5」を使った方法です。
  Win10以上などなら、この方式が一番いいかも?しれません。
  もしかしたら、Windows7以上なら、?ということかもしれません。
「.NET FrameWork3.5」が入ってさえすればいいので。)

動作速度が前述の方法よりも速い気がします。
(「File2SHA1$」関数など。)

https://www.google.com/search?q=VBA+System.Security.Cryptography+%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5+%E8%A8%88%E7%AE%97&rlz=1C1AGAK_jaJP986JP986&oq=VBA+System.Security.Cryptography+%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5+%E8%A8%88%E7%AE%97&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIKCAEQABiiBBiJBTIKCAIQABiABBiiBNIBCTEyMjY1ajBqN6gCALACAA&sourceid=chrome&ie=UTF-8

https://www.se-https://blog.nekonium.com/vba-hash/

「.NET Framework 3.5が有効になっていることを確認しましょう。」
とあるので、それがインストールされていて、
「プログラムと機能」の「Windowsの機能の有効化または無効化」にて
有効になってないとダメっぽいです。

「.NET Framework 3.5を有効にする方法」
https://www.depthbomb.net/?p=8611#toc3

ダウンロードセンターの、
「.NET Framework 3.5 Service Pack 1 (フル パッケージ:231MB:ダウンロード可能)」
https://www.microsoft.com/ja-jp/download/details.aspx?id=25150
http://go.microsoft.com/fwlink/?LinkId=122089 には、
システム必要条件に
「対応オペレーティング システム Windows Server 2003, Windows Server 2008, Windows Vista, Windows XP」
とあるので、もしかしたら、XPでも行けるかもしれません。

  
  

●コマンドもAPIも.NetFramework3.5も、「どれも使わない」場合の、DOSコマンドでテキストファイルにハッシュをゲットするプログラム

これは、コマンドもAPIも.NetFramework3.5も、「どれも使わない」場合のものです。
特にWindows2000SP4Proなどでどうしても3つの方法が使えない場合、
(=例えば社内規約によってとか、Windows2000SP4Pro自体も無いWin1000無印、とか、
 XPであっても、2つのファイルが入手できなかった場合、とか。)
に使う機会があるかもしれません。

  

  
  

●XP用の、コマンドでSHA1ハッシュをゲットするコード
(※コマンドプロンプトでのハッシュ値の割り出しの実行結果をVBA側に受け取る方式)
(※受け取り先が「配列」ではなく、普通の変数の方法)

(※コマンドを実行したあと、その結果の「数行」からハッシュ値だけを抽出
  するコードも一緒になっています。SHA256以上も計算できます。)
(※一番上のコードのように、コマンド実行結果を配列では受け取りません。
  結果の中身をループしてハッシュ値の部分を探し、それだけを
  抜き出しています。多分、一番簡単な方法です。)

ただ、XPでは、通常はすぐには使えません。
しかし、
「Windows Server 2003 Service Pack 2 管理ツール パック (x86 エディション用)」
https://www.microsoft.com/ja-jp/download/details.aspx?id=6315
をダウンロード、インストールすると、
動くようになります。

ただその際、すべてのPCにそれをインストールしなくてもOKです。
どれか1つのPCにインストールし、その完了後に、最低限必要なファイルを
2つ抜き出して、他のマシンには、それをコピペすればOKです。
(「c:\windows\system32」に。)

その2つのファイルは、
「c:\windows\system32」の、「certutil.exe」と「certadm.dll」です。

このプログラム自体はDOS窓がちらついてしまいますが、ハッシュを取得する部分を消すかコメントアウトして、1つ上のプログラムとかけあわせると、DOS窓がちらつかないようにさせることができると思います。(その場合は、最低、Waitで2秒ほど待たないといけませんが)

  

●Windows2000(SP4?Pro版)でのコマンド利用でのハッシュ計算。(Certutil.exe利用)
(※「コマンドプロンプトでのハッシュ値割り出しの実行結果をVBA側に受け取る方式」)

WindowsXPはCertutil.exeが無かったのですが、Windows2000SP4ProやServerには、
あらかじめ、Certutil.exeが入っているようです。
ただ、格納場所が「C:\WINNT\system32\dllcache」でPATHが通っていません。
なので、下記コードの「PATH_Add01()」プロシージャにて、
「C:\WINNT\system32\dllcache」にパスを通します。

ただ、まあそこは手作業でももちろんOKです。

それが完了したら、PC再起動。

基本、
①「PATH_Add01()」関数などでPATHを通してPCを再起動し、
②コマンドプロンプトで「certutil /?」が正常にヘルプ表示されるかのチェックが必要です。

なお、「cert・・・」関連のファイルのうち、
C:\WINNT\system32\と
C:\WINNT\system32\dllcacheの両方に存在して、
コマンドプロンプト画面のテストで、「序数が・・・」のエラーになるときは、
C:\WINNT\system32\dllcacheにPATHを通したあとは、
C:\WINNT\system32\側の同名のファイルをリネームすると、
エラーが出なくなることがあります。
どのファイルをリネームするかは、出てきたエラーにファイル名が出るので、
そのファイルをリネームすればOKです。
(必ずしも常に100%うまくいくとは限りませんが、今のところ、うまくいってます。)