2013-02-06

月村了衛『機龍警察』とその他の作品



機龍警察』シリーズをひと通り読んだ。初刊が出たのはけっこう前だが、SFというよりは警察ものっぽい、といった書評を読んで実はちょっと敬遠してた。だが読んでみたらどうしてどうして。本格的なエンターテイメント小説でたいそう面白かった。

基本設定をあらためてなぞるとこんな感じだ。近未来、数メートルサイズの人型ロボットである機甲兵装が普及し、各地の紛争に利用される一方、日本でも海外のマフィアやヤクザ、テロリストたちが秘密裏に持ち込んだ機甲兵装による事件が増加。警察は機甲兵装対応の特捜部を設置する。警察の切り札が、どこからか入手した、世界のほかのどこにもないような先進的な機甲兵装、竜騎兵。それに乗るのは外部から雇われた傭兵、元警官、あと元テロリストという不穏な3人……といったあたり。

言うまでもなく『パトレイバー』の強い影響下にある設定だし、仕切るリーダーは後藤隊長ほどではないにしても、腹に一物ありそうな人物だ。これまでのところのシリーズ3作品はどれも、テロや暴動事件が発端となりつつ、3人の搭乗者の過去の因縁と物語が絡み合い、進んでいく。

ただ確かに一方で、SFロボットものといった側面はあまり強調されていない。たしかにアクションもあるけれど、物語の大半は警察の捜査の話であったり、主人公たちの組織が警察内部でも異端的であることから生じる軋轢であったり、その調整や、竜騎兵の出動までの準備の段取りやシークエンスであったり、といった細部のパートが多い。そしてまた、その細部が面白いわけだ。機甲兵装は物語の設定として大事だし、3人の傭兵たちは警察小説としてはちょっとありえない設定だろうが、こういった設定が警察小説的なパートとうまく絡み合って効果を上げていると思う。

そういうわけで、非常に面白いし、本格的だった。おすすめ。

---

だが一方で、妙な違和感も感じるのである。なんといったらいいだろうか。

警察小説としての骨格と、物語の全体的なテイストからすると、「竜騎兵」といった用語はアニメチックで浮いている気がする。竜騎兵の設定も、「ドラグーン」とかルビがふられていることも。ポリス・ドラグーンが部署の正式名称であることも。機甲兵装の機種名が「ゴブリン」とかみたいなファンタジーめいていることも。あとアグリメントモードの起動コードも。なんとなくこういった設定や描写が、齟齬をきたしている気がする。なんせ基調となるのは、機甲兵装を「キモノ」とかいう隠語で呼び習わしている警察たちなのだ。部署名はポリス・ドラグーンだけど。

もっとも、齟齬といっても、これが作品全体の評価に影響を与えるような瑕疵とはいいがたい。だが、ふたつの混じり合わないテイストが混在してマーブル模様を描いているような、そういう印象を受ける。

月村了衛は自覚的にこういう齟齬を浮き立たせているのかもしれないと思う。毎回律儀にポリスデパートメントじゃなくてポリスドラグーンだ、などと説明するのは、いいかもしれないけど読者はだいたいみんな知ってるだろう。でもあえてその違和感を毎回、読者にわざわざ思い出させている。この齟齬は、竜騎兵の搭乗者である3人と警察側の人間の齟齬と相同でもあり、つまりは『機龍警察』という物語の基本構造に根ざした齟齬でもある。のかもしれない。思いつきだが。

わたしは、こういうテイストは揃っている方が気分が落ち着くたちで、だから余計に気になるのかもしれない。最初にアグリメントモードが起動したシーンを読んだとき、正直なところどうしたもんかと思ったぐらいだ。こういうのは、こういう小説で「アリ」なのか?という疑問が渦巻いたわけである。いまもちょっと渦巻いている。

---

それで思うのは、月村了衛のほかの作品である。『機忍兵零牙』はよくわからない異世界SF忍者アクション、『一刀流夢想剣 斬』は剣豪小説だが、こっちは『機龍警察』のシリーズとまるでテイストが違う。

ストーリーは単純明快、実になんてことない話である(おかげで詳細は忘れてしまった)。だが『零牙』には魅力的なSF忍術が多数登場し、主人公はキメシーンにきっちりキメ、名乗り口上を挙げたりする。ほとんど何かのパロディかというぐらいだ。『一刀流夢想剣』のほうも、剣豪小説としての骨格がよく、魅力的な悪役、敵役の剣術対主人公側の剣術といった要素も盛り上がる。

で、こういったSF忍術や剣豪ものの、ちょっとチープな気がするが魅力的な部分というのは、上で挙げた『機龍警察』に感じるぼくの違和感と、つながっている気がするのだ。ものすごく乱暴にいうと、『機龍警察』の地味で凝った部分をとっぱらって派手なアクションだけで小説を組み立てると、『零牙』などになるといってよいと思う。

そして、これはこれで面白いのだ。

どうも、月村了衛の経歴(元アニメシナリオライター)を目にしたところから来る僕自身の偏見なのだろうが、こういう派手なアクションや「マンガっぽい」設定が「本分」なのではないか? 作家的な資質と相性がいいのは、むしろ『零牙』や『一刀流夢想剣』などのような作品なのではないか? といった疑念が拭えないでいる。

ただ、相性のよしあしと作品のよしあしは別であり、けっきょくどちらのほうが面白いかといえば、やはり『機龍警察』のほうが遥かに面白い。アクションのシーンもありつつ、地味な警察パートも面白いし、物語の構造も複雑で、読後感がまるで違う。そちらのほうが向いていると思うから作者ももっぱらそっちに注力すべき、などというふうには思えない。そういう状況がまた、面白いなあと思うのだった。

ともあれ、いろんな意味で今後の作品が楽しみな作家だ。読まず嫌いをしなくてよかった。

2013-02-05

パスワード用のハッシュとは(猛省用資料)

昨日の記事はだいぶ注目を集めたようです。今日は自分向けの技術的なメモです。

パスワード等に使うのにSHAなどのよく知られたハッシュ関数ではなぜダメなのか? パスワード用のハッシュ関数は何が違うのか? という話です。なお、今回はほんとに昨日今日でいろいろ仕入れたもののため、中身も薄いし間違ってるかもしれません(また、個別のアルゴリズムやテクニックなどは陳腐化しやすいので、後日にはいろいろ変わっていることでしょう)。その辺は注意してください。

ネタ元は http://throwingfire.com/storing-passwords-securely/#notpasswordhashes など 、あと https://plus.google.com/102550604876259086885/posts/4eoNnNSQ7W6 にコメントをいただいた皆さん(ありがとうございます!)。

で。

SHAなどのハッシュ関数は、パスワード用でもいい性質を満たしているように思えます。入力文字列長に依存しない一方向関数で、元の入力の推定は難しいし、分布も一様であるらしいし(確認したことないから知らないけど……)、いい気がします。MD5やSHA1はさすがにいろいろ解析が進んでいる気がしますが、SHA256ならいまのところ安全な気がします(とはいえ、この分野の進みは速いのでいまはどうなのか……)。

ともあれ、こういうハッシュ関数はパスワードで使うには大きな欠点があるようです。それは速すぎることなのだそうです。

こういうハッシュ関数は、ダウンロードするパッケージとかCDやDVDのイメージとかの検証にも使える規模ですから、物凄く高速でスループットもいい。数Mバイトや数Gバイトでも数秒、数十秒で完了してしまいます。パスワードは数文字から、せいぜい数十文字といったところでしょう。こんなものは0.01ミリ秒とかで計算できてしまう。

そうすると、辞書攻撃で数万パターンのハッシュ値を計算しなければならないとしてもせいぜい数秒で完了しちゃいます。ソルトがあってパターン数が数千万になっても数日規模となっては、イカンわけです。

そもそもログイン時の処理について言えば、パスワードのチェックが0.01ミリ秒で終わろうが、0.1秒かかろうが、ユーザエクスペリエンスにはそれほど大きな影響はないはずです。ということは、1万倍遅くても問題ないというか、1万倍の手間をかけさせるぐらいはなんてことない。

というわけで、ハッシュの計算をたとえば1万倍繰り返して、その結果を求めるとか、そういう手間をかけさせる、といったことをしたほうが安全であるということです。こういう処理を stretching というようです。

もちろん、実際には、単に「1回目のハッシュ値を2回目の入力にし……」のような単純な連鎖にはなりません。もっと複雑にあれこれやります。なぜかというと……メモ化とかを防ぐからかな?

実際に、上のリンクで挙げられているパスワード的に安全なハッシュ関数は3つあります。

PBKDF2 は、OpenSSLなどに入っている手法です。HMACを使ってパスワードとソルトからハッシュをとって、パスワードとハッシュからまたハッシュをとって……みたいなのを繰り返して、xorして結合するみたいなイメージ。自然言語で説明するのは困難なのでリンク先ウィキペディアを眺めたほうがわかりやすいと思いました。

bcryptはBlowfishを使ったメッセージハッシュです。Blowfishは共通鍵暗号だったはずだが……と思ったのですが、ウィキペディアを見てもきちんと理解できたかは怪しいです。怪しいですが、入力キーとソルト、およびイテレーション回数に応じてキースケジュールを進めていき、そのキーを使って、ある固定の文字列を何回も何回も符号化するといった処理のように見えました。ちなみにbcryptはOpenBSDのパスワードハッシュに使われているとのこと。これも論文を読みたいと思います。

scryptはいっそう厄介ですが、 memory-hard なアルゴリズムを使ったハッシュということです。作者の論文によれば、使用メモリ量が大変でなければハードウェアに実装したり超並列化したりといったことが容易になるので、「どうあっても空間計算量が高くなるようなステップ」を間に挟むことで、超並列化しづらくするようにした由。コンセプトはわかったけれども、論文はまだ読み始めたところなので詳細はわかりません(すいません)。

さて、そういう訳で後半は腰砕けになってしまいましたが、ひとまずリソースへのリンクを自分用に貼って、読み進めたいなあと思っているわけです。

ただし、はじめのほうに書いたことを繰り返しておくと、こういう内容はすぐに陳腐化するので気をつけたほうがよいように思います。たとえばbcryptはライブラリも揃っていて使いやすそうでいいのかな、と思うと、 don't use bcrypt などというブログが出てきたりするわけです。1年後にどうなっているかはわからないので、後日この記事を読んだ人は、現状を調査することをおすすめしておきたいと思います。

2013-02-04

パスワード保存とソルトの話

先日、twitterへのハッキング行為が発見された、という発表がなされました。一部のユーザのデータが漏洩したということです。

この件について個人的に懸念を感じたため、それをこちらに書いておきました。原文では encrypted/salted password と呼ばれていたものが、日本語の公式ブログでは「暗号化されたパスワード」となり、これが朝日新聞では「パスワード」と表記されているという問題です。

専門知識があれば、ここにどういう違いがあるかはわかるのですが、そうでなければわからないのも無理はありません。しかし、わからないからといって省略して良いわけでもありません。パスワードと encrypted/salted password は大きく異なります。

ではどう違うのか? この話について、ひと通りの解説をしてみるのも良いのではないかな、と思ったのでしてみます。

「パスワード」は保存されない

さて、twitterやらなんやら、といったウェブサービスを利用するには通常、ログインをします。つまり、みなさんも自分の twitter の ID とパスワードを入力してログインのボタンを押します。twitterのIDは誰でもわかりますが、パスワードを知っているのは(ふつうは)自分だけなので、自分がアクセスしているということがわかるわけです。

みなさんがログインボタンを押すと、twitterのIDとパスワードがtwitterに送信されます(ちなみに、この送信経路はSSLというテクノロジーで暗号化されているので、送信経路で誰かが盗聴していてもパスワードがばれることはありません)。twitterでは、このIDとパスワードの組み合わせを社内に持っているデータベースで検証して、正しければユーザのログインを許しますし、間違っていればエラーを出します。

ただし、実はtwitter社のデータベースにはパスワードそのものは保存されていません(いや、中の人じゃないので本当のところは知らないけれど、されていないと思います。その前提で以下の文章は書き進めて最後に補足します)。パスワードを忘れちゃった、という問い合わせをしても、twitterはパスワードを教えてくれませんよね。データベースにないから、教えようにも教えられないんです。そこでパスワードを再発行するためのリンクを送ってくるんです。

じゃあ何が保存されているのか? 実はtwitterでは、入力されたパスワードのデータに基づいて、何らかの計算を行っています。で、その計算結果だけを保存しています。これをハッシュ値といっています。

たとえば……そうですね、コンピュータの通信というのは結局デジタルですから、どんなパスワードも0と1で符号化されています。この0の数と1の数を数えて、かけあわせた数、というのはどうでしょうか。入力パスワードが決まれば、この値も決まります。

もちろん、これは私がいまここで思いついた計算方法で、現実にはまったく役に立ちません。本当はもっと複雑なことをします。パスワードの保存に役に立つ計算方法、というのはややこしい話なので、ちょっと後回しにしますが、とにかくそういう計算方法の物凄く複雑なやつ、というのを何かやっていると思ってください。

というわけで、上の続きです。みなさんがログインボタンを押します。するとIDとパスワードが送信されます。twitter社は受け取ったパスワードが正しいのかどうかを知りたいのですが、正しいパスワードそのものは保存していません。そこで受け取ったパスワードに、同じ計算を施します。で、計算結果の数値であるハッシュ値が、保存してあるものと同じである場合は、入力したパスワードも同じと判断してログインを許可します。

なぜこんなことをするの? それって安全なの?

まさに、今回おきたような問題を回避するために、こういうことが行われています。

万が一に、何者かによって侵入され、データベースにアクセスされてしまったとしても、パスワードそのものは保存していませんから、侵入者にもパスワードはわかりません。また、不届きな従業員がパスワードを覗き見たりすることもない、といった効果もあるでしょう(でもまあこれは副次的なものだと思います)。

安全なのか? というのは、もちろん計算方法によります。計算方法は様々な条件を満たさないといけません。たとえば、ハッシュ値からもとの入力をかんたんに復元できてしまったら意味がありませんよね。また、全く違う入力なのに、簡単に同じハッシュ値になってしまうようでは、すぐ間違ったパスワードでの侵入を許してしまうため、問題があります(上でわたしが例として書いた計算方法はこの問題があります)。さらにいうと、パスワードの文字数に制限はないほうがいいでしょう。何文字ででも計算ができるような式でないといけません。また、文字数が長いほうが計算結果が大きくなるとか、そういったわかりやすい関係があると、ハッシュ値からもとの入力を完全には復元できないにしても、傾向がわかってしまうため、あまりよろしくありません。計算結果の数値の範囲は固定で、しかも均等にばらけていることが望ましいと言えます。

こういう条件を満たすような計算方法を考えろ、と言われても大変な気がしますが、幸いにして数学者や暗号学者の手によっていくつかの計算方法が提案されています。私もこの分野には明るくなかったのですが、パスワード専用の手法はいくつも提案されていて、PBKDF2やbcrypt、scryptなどといったものがあるようです(詳細は専門的すぎるので省きます。SHA1などの普通の手法を思いついたエンジニアは猛省しましょう……俺のことですが)。

いずれにせよ、こうした式を使ったハッシュ値からはもとの入力をうかがい知るのは難しいため、こういうよく知られた関数を使えば、ひとまず安心であろうと思われます。

辞書攻撃

ところが頭のいい人がいたもので、いまではこのハッシュ値でも安全でない可能性が指摘されています。計算結果からもとのパスワードを割り出す方法そのものは見つかっていないのですが、ハッシュ値に対してもとのパスワードをうまく見つけ出す方法があるのです。その有力な手法のひとつが辞書攻撃です。

辞書攻撃、という名前は面白いですが、やることはすごく単純です。計算方法がよく知られているので、ユーザがパスワードに使いそうな文字列("abcd" とか)を入力してやれば、計算結果もすぐに計算できます。

今回のように25万人のデータが抜き出したとすると、そのうち何人かはこういう適当なパスワードを使っているかもしれません。ですから、ハッシュ値だけしかなくても、よくある単語からハッシュ値を計算してみればよく、その計算結果と一致した人がいれば、その人のパスワードはその「よくある単語」だということがわかるわけです。

さらに、よくある単語リストから単語同士を組み合わせたり、oを0に置き換える、みたいなよくあるパターンを作り出すプログラムを書いてしまえば、ちょっと凝った程度のパスワードはみんな機械的にリストアップできます。で、そのリストのすべてのハッシュ値を計算するプログラムを書いてしまえばいい。ちょっと凝った程度のパスワードは、だいたいこれですべて破られてしまうでしょう。こういうよくある単語リストみたいなものを「辞書」と呼んでいるため、こういう名前になっています。

さらに言うと、そんな計算結果などは、データを抜き出したあとでのんびり計算するまでもなく、事前に計算しておいて手元のデータベースに保存しておけばいいのです。そうすれば単に比較するだけでパスワードを割り出せてしまいます。これをレインボーテーブルといいます。

複雑なパスワードにしておけば、こういうパターンとは合致しないため、ハッシュ値が渡ったとしても過度に心配することはないかもしれません。ただし、侵入者がどういう手法でパスワードを生成するか、ということは予想もつかないことなので、安心はできません。自分では凝りに凝ったつもりが、コンピュータにしてみればわりと単純だった、というのもよくあることですので。

ソルトによる攻撃耐性

さて、以上の前提を経てようやくソルトの話ができます。

データベースにハッシュ値しか保存しなかったとしても、辞書攻撃やレインボーテーブルによる解析には対抗できません。対抗できないのですが、攻撃側の手間を増大させる方法があります。それがソルトです。

ソルトは単なるランダムなデータです。ユーザがアカウント作成時にパスワードを決めたとき(もしくはパスワードを再発行したとき)、twitterの側でランダムに生成します。そして、パスワードからハッシュ値を計算するのではなく、ソルトとパスワードを連結したものに対してハッシュ値を計算します。そして、ハッシュ値とソルトの両方を保存しておきます。

というわけで、本当のログインはもうちょっと複雑です。ログインボタンを押してIDとパスワードが送信されると、twitter社はまずデータベースを調べ、ソルトを発見します。そしたらソルトと入力されたパスワードを連結し、そのハッシュ値を計算します。で、ハッシュ値が一致していればログインを許可します。

このソルト自体にはまったく意味がないように思えるかもしれません。単に計算の手間を増やしているだけに思えます。実際、私ひとりのパスワードのハッシュ値が漏洩したとして、これを辞書攻撃で解析しようとした場合、ソルトがあるかどうかはほぼ関係がありません。だってソルトはわかっているので、同じようによくある単語パターンからハッシュ値を計算すればよいだけだからです。

ですが、今回のように数万人といったユーザのデータが漏洩した場合には確実に意味があります。

まず、レインボーテーブルの攻撃を無効化できます。あらかじめ計算しておこうにも、ソルトというのはランダムな文字列ですから、よくあるパスワード文字列に加えて、可能なランダムパターンすべてを連結して事前に計算しておくことは、事実上不可能になってしまいます。

また、レインボーテーブルを用いない場合でも、攻撃者の手間はすごく増えます。25万人分のソルトのないデータベースに対して辞書攻撃をしたい、とします。パスワードのパターンは1000個ぐらい作ったとしましょう。そうしたら1000個のハッシュ値を作る必要があります。たとえば "abcd" というパターンに対してハッシュ値を計算したら、25万人分のハッシュ値のなかから一致するものを見つけ出せばいいのです。

これがソルトになると、話はそう簡単ではありません。たとえばAさんとBさんのパスワードが両方たまたま "abcd" だったとしても、ふたりのソルトは(ランダムに生成されているので)異なっており、したがってハッシュ値も違っています。ということは攻撃者は、Aさんのソルトを見て、"abcd"とそのソルトからハッシュ値を計算し、比較したとしても、その計算結果はBさんのパスワードを解析するときには一切使えなくなります。このため、1000x250000個のハッシュ値を計算しないといけなくなります(比較回数は同じですが、まあ比較するのはそれほど大変ではありません)。ハッシュ値の計算はそれほど時間がかからないのですが(でないとログインに時間がかかってしまいます)、上で説明したように様々な条件を満たすためにけっこう複雑な計算はしています。それの計算回数が25万倍になったら、相当な手間になるな、というわけです。

こういうわけで、大規模な情報漏えいに対しては、ソルトは大きな意味を持ちます。ただし、「攻撃の手間を増やす」といった程度の差しかなく、本質的に安全性が増すわけではありません。

ハッシュ値とか、ソルトの有無って、報道する上でそんなに大事なの

大事だと思います。

まず、パスワードそのものを保存するウェブサービスだった場合、大変な問題が起きます。全員の全パスワードが攻撃者の手元にそのまんま来るからです。慌てて変えても手遅れである危険性がとても高いです。

また、私がちょっとした封筒の裏の計算をしてみたところでは、ソルトなしのパスワードハッシュの場合、パターン生成の規模にもよりますが長くても数日以内にすべての解析が完了すると思います。そもそもソルトがないのであれば、レインボーテーブルを使えばよく、その場合はその日のうちに解析が完了します。レインボーテーブルがある場合、記事を見る頃にはやはり手遅れであろうと思います。ただしハッシュが漏洩した場合は、辞書攻撃ではバレないような凝ったパスワードを使っていたユーザについては、実は問題がなかったということになります。

ソルトがある場合、レインボーテーブルは使えませんし、この「数日」というのが一人あたりにかかるコストになります。ちょっとパターン数を少なくして、ひとりあたり1日かけるとしても、全員の解析が完了するのは250000日後ですから、全然現実的ではありません。もっとも、この処理は簡単にそのまま並列化できます。1万台のコンピュータがあれば25日で完了します。とはいえ、何日以上かの猶予はあるとみなせるのではないでしょうか。

以上のことから、私が個人的に感じたところでは、

  • パスワードそのものの漏洩というのは、報道されるころにはとっくに手遅れになっていて、わたしたちにはなすすべもない
  • パスワードのハッシュ値(ソルトなし)の場合、攻撃者はふつうレインボーテーブルを使うことが予想されるので、やはり手遅れである可能性が高い。レインボーテーブルがなければじゃっかんの猶予はあるかも
  • ソルトがある場合は、攻撃者に計算機資源がない場合は全員に対する解析をあきらめさせるほどの負荷がかかる。また、どれだけ頑張ってもおそらく何日間か以上の猶予はあるので、報道されてからパスワードを変えても意味はある
……といった差があるだろうと思います。

ようは、「パスワードが漏洩した」という報道は「こんな風に被害を受けた人がいる」という話ですが、「ソルト付きパスワードのハッシュ値が漏洩した」というのは「急いで対処してください」という注意喚起であるといった差もあるだろうと思います。


以上の情報から、ぼくたちは何をすべきか

実は、当初の公式発表となんら変わりません。
最低でも10文字、大文字と小文字、数字、記号などを混ぜたパスワードをご利用下さい。また、パスワードの使い回しは情報へのアクセスの可能性を大きくしますので、他のサービスとは同じパスワードを利用されないことをお勧めします。
第一に、パスワードの共有化を避けるということです。パスワードをなんのために盗むかというと、twitterを乗っ取るというよりは、他のサービスにログインするといったことがあると思います。実際、今回はtwitter側が、漏洩した可能性のある全員に対してパスワードをリセットするなどの処置を行ったため、乗っ取られる心配は、とりあえずなくなりました。でもtwitterのパスワードを銀行のパスワードと同じにしていたら、銀行口座を操られる可能性がありますし、gmailと同じにしていたら機密のメールが読まれる可能性があります。こういった問題を防ぐには、パスワードの共通化を避けること、gmailなどに二段階認証を導入することです。

第二に、コンピュータに予測されづらいパスワードを使うことです。パスワードそのものを保存せず、ハッシュ値のみを保存する場合の有効な攻撃手段は、辞書攻撃ぐらいしか知られていません。しかもおそらく攻撃者は、人間がよく使うであろうパスワードから順番に試します。凝れば凝るほど、自分のパスワードがばれるまでにはより時間がかかるようになり、最終的には攻撃者が諦めるといったことが考えられます。

で、なんなの? ほんとにそうだって誰が言えるの?

ぼくは中の人ではないし、セキュリティについても明るくないので、上で書いたような内容がすべて見当違いであり、本当はもっと違った仕組みでパスワードを保存しているかもしれないし、漏洩したデータが全然違うといった可能性もあります。

ですが(細かい手法はさておき)パスワードを保存する場合にハッシュを使うとかソルトを入れるとかいった事柄は、ソフトウェアエンジニアリングでは広く知られた手法であり、これでない手法を取っているということは考え辛いことです。また「ソルト」というのも、パスワードをハッシュで保存するという場合にのみ使われる概念なので、ソルトを使っている、と言及したということはつまりこういったやり方でパスワードを保存していると考えてよいだろうと思います。(追記: ソルトはほかの暗号化手法でも出てくることがあるのに気づきました。OpenSSHのパスフレーズから鍵を生成するところとか。でもまぁ、やっぱこっちなんじゃないかなあ、と私は思っています)