yoshida_eth0の日記 このページをアンテナに追加 RSSフィード

2010-08-14

Dropboxの仕様を調べてみた

セキュリティ部分について調べるつもりが、何か別の所まで調べてしまった気がする。

 

C:\Documents and Settings\USERNAME\Application Data\Dropbox\host.db

1行目

16進数表記の文字列。

16進数表記で40バイト。

バイナリ表記で20バイト。

 

2行目

Base64エンコードされた、Dropbox Folder Location。

 

C:\Documents and Settings\USERNAME\Application Data\Dropbox\dropbox.db

sqlite形式のデータベースファイル。

テーブルは以下3個。

block_cache
config
file_journal

 

configテーブル

設定が保存されてる。

1行でKeyとValue。

CREATE TABLE config (
    id INTEGER PRIMARY KEY,
    key TEXT NOT NULL UNIQUE,
    value TEXT
);

 

config.keyカラム

設定項目名。

sqlite> select id, key from config;
1|schema_version
2|last_revision
3|root_ns
4|host_id
5|email
6|ns_p2p_key_map
7|recently_changed3

 

config.valueカラム

PythonのPickleでシリアライズされたものをBase64でエンコードしてある。

デコードするPythonプログラム。

#!/usr/local/bin/python
# set encoding=utf8

import sys, base64, pickle

def main():
	input = sys.argv[1]
	input = base64.b64decode(input)
	print pickle.loads(input)

def usage():
	print 'Usage: %s encoded_str' % sys.argv[0]

if __name__=='__main__':
	if (len(sys.argv)==2):
		main()
	else:
		usage()

 

config.value (WHERE key='schema_version')

型 : int

値 : 6

 

config.value (WHERE key='last_revision')

型 : Dict

値 : {ルートNS: 見せられないlong}

ファイルを追加したりすると増えるのかもしれない。

リビジョンにしては数がでか過ぎる。

全ユーザ共通?とも考えたけど、コミットしても値は変わらない。

 

config.value (WHERE key='root_ns')

型 : long

いろんな所でキーとして使われている。

見せていいものか悪いものか解らないから、とりあえず「ルートNS」と表現する。

 

config.value (WHERE key='host_id')

型 : str

16進数表記で32バイト。

MD5っぽい。

 

config.value (WHERE key='email')

型 : str

メールアドレス。

 

config.value (WHERE key='ns_p2p_key_map')

型 : Dict

値 : {ルートNS: (u'-----BEGIN CERTIFICATE-----\n見せられない\n-----END CERTIFICATE-----\n', u'-----BEGIN RSA PRIVATE KEY-----\n見せられない\n-----END RSA PRIVATE KEY-----\n', '見せられない')}

1つ目のstrは、RSA公開鍵。

2つ目のstrは、RSA秘密鍵。

3つ目のstrは、パスフレーズ?初期ベクトル?

MD5っぽい。

詳細不明。

 

公開鍵と秘密鍵はペアになっていた。

この使い方、公開鍵暗号方式として間違ってる気がする。

このペア、サーバ側にも置いてあるはず。

こんな使い方をするなら、Diffie-Hellmanとかでその都度鍵交換してもいいような気がする。

けど、それだと1回の通信の為に2回接続しなきゃいけない。

多分そこが問題だったから、こういう奇妙な形になったんだと予想。

 

サーバにサーバ秘密鍵とクライアント公開鍵、クライアントにクライアント秘密鍵とサーバ公開鍵、を入れれば、RSAを使って1回の通信で更にセキュアになる。

サーバとクライアントでRSAキーを分けない理由は不明。

多分面倒だったんだと思う。

再発行出来なくなるし。

 

クライアントを再インストールしたら、このRSAキーが復活してた。

もしかしたら、サーバから送られてきてるのかもしれない。

 

ペアになっている事を確認するPHPのプログラム。

<?php
$public = '-----BEGIN CERTIFICATE-----
見せられない
-----END CERTIFICATE-----';

$private = '-----BEGIN RSA PRIVATE KEY-----
見せられない
-----END RSA PRIVATE KEY-----';

// 文字列からキーリソース生成
$public = openssl_pkey_get_public($public);
$private = openssl_pkey_get_private($private);

// 暗号化するデータ
$data = 'あいうえお!';

// public keyで暗号化
openssl_seal($data, $sealed_data, $env_keys, array($public));

// private keyで復号化
openssl_open($sealed_data, $open_data, $env_keys[0], $private);

echo $open_data."\n";

 

公開鍵の詳細。

どうやらこのキーはクライアント側で生成してるらしい。

$ openssl x509 -in public.crt -text
Certificate:
    Data:
        Version: 4 (0x3)
        Serial Number: 1 (0x1)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=dropbox-client
        Validity
            Not Before: Jan  1 00:00:00 1970 GMT
            Not After : Jul 18 17:14:19 2030 GMT
        Subject: CN=dropbox-client
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1536 bit)
                Modulus (1536 bit):
                    見せられない
                Exponent: 見せられない (見せられない)
    Signature Algorithm: sha256WithRSAEncryption
        見せられない
-----BEGIN CERTIFICATE-----
見せられない
-----END CERTIFICATE-----
$ openssl asn1parse -in public.crt
    0:d=0  hl=4 l= 548 cons: SEQUENCE
    4:d=1  hl=4 l= 333 cons: SEQUENCE
    8:d=2  hl=2 l=   3 cons: cont [ 0 ]
   10:d=3  hl=2 l=   1 prim: INTEGER           :03
   13:d=2  hl=2 l=   1 prim: INTEGER           :01
   16:d=2  hl=2 l=  13 cons: SEQUENCE
   18:d=3  hl=2 l=   9 prim: OBJECT            :sha256WithRSAEncryption
   29:d=3  hl=2 l=   0 prim: NULL
   31:d=2  hl=2 l=  25 cons: SEQUENCE
   33:d=3  hl=2 l=  23 cons: SET
   35:d=4  hl=2 l=  21 cons: SEQUENCE
   37:d=5  hl=2 l=   3 prim: OBJECT            :commonName
   42:d=5  hl=2 l=  14 prim: PRINTABLESTRING   :dropbox-client
   58:d=2  hl=2 l=  30 cons: SEQUENCE
   60:d=3  hl=2 l=  13 prim: UTCTIME           :700101000000Z
   75:d=3  hl=2 l=  13 prim: UTCTIME           :300718171419Z
   90:d=2  hl=2 l=  25 cons: SEQUENCE
   92:d=3  hl=2 l=  23 cons: SET
   94:d=4  hl=2 l=  21 cons: SEQUENCE
   96:d=5  hl=2 l=   3 prim: OBJECT            :commonName
  101:d=5  hl=2 l=  14 prim: PRINTABLESTRING   :dropbox-client
  117:d=2  hl=3 l= 221 cons: SEQUENCE
  120:d=3  hl=2 l=  13 cons: SEQUENCE
  122:d=4  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  133:d=4  hl=2 l=   0 prim: NULL
  135:d=3  hl=3 l= 203 prim: BIT STRING
  341:d=1  hl=2 l=  13 cons: SEQUENCE
  343:d=2  hl=2 l=   9 prim: OBJECT            :sha256WithRSAEncryption
  354:d=2  hl=2 l=   0 prim: NULL
  356:d=1  hl=3 l= 193 prim: BIT STRING

 

config.value (WHERE key='recently_changed3')

型 : list

値 : [(u'ルートNS:/Public/How to use the Public folder.rtf', 0), (u'ルートNS:/Photos/Sample Album/Pensive Parakeet.jpg', 0), (u'ルートNS:/Photos/Sample Album/Costa Rican Frog.jpg', 0), (u'ルートNS:/Photos/Sample Album/Boston City Flow.jpg', 0), (u'ルートNS:/Photos/How to use the Photos folder.rtf', 0)]

file_journal.server_pathが5個入ってた。

keyの通り、最近更新されたファイル。

新しいものが先頭に追加されるらしい。

タプル2つ目はリビジョンかと思ったけど違うらしい。

ファイルを追加・更新したら0。

ファイルを削除したらNULL。

 

block_cacheテーブル

ファイルのキャッシュ(ログ)。

ファイルを追加・更新すると1行増える。

ファイルを削除しても、追加も削除もされない。

CREATE TABLE block_cache (
    id INTEGER PRIMARY KEY,
    hash VARCHAR(43) NOT NULL UNIQUE,
    sig TEXT,
    size INT,
    delete_after INT,
    needed_for INT
);

 

block_cache.hashカラム

43文字のASCII文字列。

file_journal.active_blocklistと一致。

Base64エンコードされた文字列かと思いきや、なんとなく違う。

多分プログラムがユニークになるように生成してる。

 

block_cache.sigカラム

Base64エンコードされた文字列。

ファイルのサイズに応じて長くなるらしい。

keyから察するに、署名だと思われるが、長さが違う気がする。

最初の16文字(バイナリ表記で12バイト)は全ての行で一致していた。

 

block_cache.sizeカラム

ファイルのサイズ。(バイト数)

コミット時、file_journal.active_sizeと一致。

 

block_cache.delete_afterカラム

全部0。

詳細不明。

 

block_cache.needed_forカラム

全部NULL。

詳細不明。

 

file_journalテーブル

ファイル一覧。

ファイルを追加すると、このテーブルに1行追加される。

ファイルを削除すると、このテーブルから物理削除される。

CREATE TABLE file_journal (
    id INTEGER PRIMARY KEY,
    server_path TEXT NOT NULL UNIQUE,
    active_server_path TEXT,
    active_blocklist TEXT,
    active_mtime INT,
    active_size INT,
    active_sjid INT UNIQUE,
    active_dir INT,
    active_attrs TEXT,
    updated_server_path TEXT,
    updated_blocklist TEXT,
    updated_mtime INT,
    updated_size INT,
    updated_sjid INT,
    updated_dir INT,
    updated_attrs TEXT,
    on_disk TINYINT
);

 

file_journal.server_pathカラム

値 : ルートNS:/photos/how to use the photos folder.rtf

日本語はそのまま日本語で入っていた。

 

file_journal.active_server_pathカラム

file_journal.server_pathと一致。

 

file_journal.active_blocklistカラム

block_cache.hashと一致。

file_journal.server_pathがディレクトリの場合は空文字列。

 

file_journal.active_mtimeカラム

ファイルを最後に更新(コミット?)した時間。

Unixtime。

 

file_journal.active_sizeカラム

ファイルのサイズ。(バイト数)

最終更新のblock_cache.sizeと一致。

file_journal.active_dirが1の場合は0。

 

file_journal.active_sjidカラム

詳細不明。

UNIQUEのint。

 

file_journal.active_dirカラム

ディレクトリだったら1。

ファイルだったら0。

 

file_journal.active_attrsカラム

config.valueと同様、PickleでシリアライズされたものをBase64でエンコードしたもの。

デフォルトで入ってたファイルは{}で、自分で追加したファイルはNULLだった。

LinuxとかMacとかで使った時に、パーミッションとか属性とかが入るのかも知れない。

 

file_journal.updated_server_pathカラム

詳細不明。

全部NULLだった。

 

file_journal.updated_blocklistカラム

詳細不明。

全部NULLだった。

 

file_journal.updated_mtimeカラム

詳細不明。

全部NULLだった。

 

file_journal.updated_sizeカラム

詳細不明。

全部NULLだった。

 

file_journal.updated_sjidカラム

詳細不明。

全部NULLだった。

 

file_journal.updated_dirカラム

詳細不明。

全部NULLだった。

 

file_journal.updated_attrsカラム

詳細不明。

全部NULLだった。

 

file_journal.on_diskカラム

詳細不明。

全部1だった。

 

登録からセキュアな通信までの流れ(妄想)

登録

・クライアントソフトインストール。

・RSA生成。

・ユーザ情報・RSA登録。

 

入力するemail/passは人間(ブラウザ)認証用。

バックグラウンドで生成されるRSAはデータ暗号化用。

 

通信

・RSA公開鍵でデータ暗号化。

・送る。

・RSA秘密鍵でデータ復号化。

 

パケットを見る限り、443ポートとやりとりしてる。

暗号化したデータをHTTPSで流してる気がする。(2重で暗号化)

RSA-encryption over HTTP over SSL

HTTP(アプリケーション層)の上に仮想的なレイヤー(Dropboxの独自仕様)を作ってその上で動かす。

レイヤーと言える程きっちりしたものではないかもしれないけど。

これは前に作ったOAuth Encryptionに似てる。

 

データ部分は2重で暗号化されているとして、何かユニークなIDを普通のHTTPSで見れる状態で送ってるはず。

考えられるユニークIDは、email位しかなさそう。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/eth0jp/20100814/1281739001
Connection: close