CAPICOM で暗号・復化 (おまけ)

d:id:imatake:20100128:1264664083 の続きというかおまけ、Java は javax.crypto.Cipher で、VBS は CAPICOM を利用して、AES 暗号をする。

CAPICOM の暗号データ

では、CAPICOM で出力される暗号データはなんなのか。

MSDN ライブラリEncryptedData Object のを見てみると以下の様な記述がある。

Note CAPICOM does not support the PKCS #7 EncryptedData content type but uses a nonstandard ASN structure for EncryptedData. Therefore, only CAPICOM can decrypt a CAPICOM EncryptedData object.

EncryptedData Object (MSDN)

機械翻訳してみる。(Infoseek マルチ翻訳)

注CAPICOMはPKCS #7 EncryptedData内容タイプをサポートしないで、EncryptedDataのために非標準ASN構造を使用します。したがって、CAPICOMだけはCAPICOM EncryptedData物を解読することができます。

どうも「PKCS #7」を使わず、「ASN データ構造」を使用する。そのため、CAPICOM の暗号データは、CAPICOM しか読み解けない事になってしまう。

CAPICOM の暗号データ ASN データ構造

CAPICOM の暗号データは、ASN データ構造らしいので、ASN.1 encoder/decoder on JavaScript を使って、内容をデコードしてみる。

CAPICOM の暗号データ(Base64)

MIGCBgkrBgEEAYI3WAOgdTBzBgorBgEEAYI3WAMBoGUwYwIDAgABAgJmDgICAIAE
EAAAAAAAAAAAAAAAAAAAAAAEENk3JQEmcgvYnbAd/egSfLoEMB0hne2Dg0Tsyn1t
gUi8XwRv/4ex8aQZLHjK0zfBhlzQRK54+7tJUMnEPtBFK1KA/A==

ASN データ構造

SEQUENCE {
   OBJECTIDENTIFIER 1.3.6.1.4.1.311.88.3
   [0] {
      SEQUENCE {
         OBJECTIDENTIFIER 1.3.6.1.4.1.311.88.3.1
         [0] {
            SEQUENCE {
               INTEGER 020001 : Too long Integer. Printing in HEX.
               INTEGER 660e : Too long Integer. Printing in HEX.
               INTEGER 0080 : Too long Integer. Printing in HEX.
               OCTETSTRING 00000000000000000000000000000000
               OCTETSTRING d937250126720bd89db01dfde8127cba
               OCTETSTRING 1d219ded838344ecca7d6d8148bc5f046fff87b1f1a4192c78cad337c1865cd044ae78fbbb4950c9c43ed0452b5280fc
            }
         }
      }
   }
}

バイナリ値と照らし合わせてみる。

// SEQUENCE
0x30 0x81 0x82
// OBJECTIDENTIFIER 1.3.6.1.4.1.311.88.3
0x06 0x09
0x2B 0x06 0x01 0x04 0x01 0x82 0x37 0x58 0x03
// [0]
0xA0 0x75
// SEQUENCE
0x30 0x73
// OBJECTIDENTIFIER 1.3.6.1.4.1.311.88.3.1
0x06 0x0A
0x2B 0x06 0x01 0x04 0x01 0x82 0x37 0x58 0x03 0x01
// [0]
0xA0 0x65
// SEQUENCE
0x30 0x63
// INTEGER 020001
0x02 0x03 
0x02 0x00 0x01
// INTEGER 660e
0x02 0x02
0x66 0x0E
// INTEGER 0080
0x02 0x02
0x00 0x80
// OCTETSTRING 00000000000000000000000000000000
0x04 0x10
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
// OCTETSTRING d937250126720bd89db01dfde8127cba
0x04 0x10
0xD9 0x37 0x25 0x01 0x26 0x72 0x0B 0xD8 0x9D 0xB0 0x1D 0xFD 0xE8 0x12 0x7C 0xBA
// OCTETSTRING 1d219ded838344ecca7d6d8148bc5f046fff87b1f1a4192c78cad337c1865cd044ae78fbbb4950c9c43ed0452b5280fc
0x04 0x30
0x1D 0x21 0x9D 0xED 0x83 0x83 0x44 0xEC 0xCA 0x7D 0x6D 0x81 0x48 0xBC 0x5F 0x04
0x6F 0xFF 0x87 0xB1 0xF1 0xA4 0x19 0x2C 0x78 0xCA 0xD3 0x37 0xC1 0x86 0x5C 0xD0
0x44 0xAE 0x78 0xFB 0xBB 0x49 0x50 0xC9 0xC4 0x3E 0xD0 0x45 0x2B 0x52 0x80 0xFC


追記
最初の「INTEGER 020001」は常に固定?2つ目の「INTEGER 660e」はアルゴリズムの設定値で、3つ目の「INTEGER 0080」は 0x80(=128) なのでキーの長さ(ブロックサイズが正しい?)。
4つ目の「OCTETSTRING」は不明、5つ目の「OCTETSTRING」は毎回128bitで値が変わるのでIV、最後の「OCTETSTRING」が暗号化された値。
と言ったところか。


追記
忘れてた。VBScript は内部的には、UTF-16LE が使われる。文字列のハッシュ値が合わなくて悩んだ…。