kakke18’s blog

ゆるふわ学生エンジニア

Solidityに触れてみた

2/9,16,17日にブロックチェーンハッカソンに参加してきました!

そこで、SolidityというEthereum上で動くスマートコントラクト開発言語に初めて触れたので知識をメモしておきます。

修飾子

  • アクセス修飾子
アクセス修飾子 内部 継承先 外部
public
external × ×
internal ×
private × ×
  • 状態修飾子

    • pure:storageの読み込み、書き込み不可
    • view:storageの読み込みは可能、書き込みは不可能
    • payable:Etherを受信可能
    • modify:カスタムの修飾子

変数の種類

  • memory:一時的に保持される変数、gas不要
  • storage:ブロックチェーンに永久に保持される、gas要

文字列比較

  • 文字列を直接比較することはできない
  • ABIでエンコードし、keccak256でハッシュ化(bytes32型に変換)
function isSameString(string memory origin, bytes32 target)
    private pure returns (bool) {
    return keccak256(abi.encodePacked(origin)) ==keccak256(abi.encode(target));
}

文字列連結

  • str1 + str2みたいなことは不可能
  • bytes型
    • .lengthメンバを使える
    • 添え字が使える
    • 動的配列なのでサイズを確保(mallocのようなもの)
function strConnect(string memory str1, string memory str2)
    private returns(string memory) {
    bytes memory strbyte1 = bytes(str1);
    bytes memory strbyte2 = bytes(str2);
    bytes memory str = new bytes(strbyte1.length + strbyte2.length);
    uint8 point = 0;
    for(uint8 i = 0; i < strbyte1.length; i++) {
        str[point] = strbyte1[i];
        point++;
    }
    for(uint8 i = 0; i < strbyte2.length; i++){
        str[point] = strbyte2[i];
        point++;
    }
    return string(str);
}

文字列→Bytes32

function stringToBytes32(string memory source)
    private returns (bytes32 result) {
    bytes memory tempEmptyStringTest = bytes(source);
    if (tempEmptyStringTest.length == 0) {
        return 0x0;
    }
    assembly {
        result := mload(add(source, 32))
    }
}

感想

人類にとってスマコン開発は早すぎた。

参考

なぜパスワードはハッシュ化されるのか

昨日のブログでパスワードは ハッシュ化されて保存されていると書きました。 では、なぜ暗号化ではなく、ハッシュ化されるのでしょうか。 それは、パスワードを保存するという目的の上では、ハッシュ化の方が優れているからです。

暗号とは

みんな大好きWikipediaには、このように記載されています。

暗号とは、セキュア通信の手法の種類で、 第三者が通信文を見ても特別な知識なしでは読めないように変換する、 というような手法をおおまかには指す。

つまり、暗号とは、特定の誰かのみに情報を伝達するための手段なのです。特定の誰かを判断するには、特別な知識が必要となります。これをといいます。

シーザー暗号

暗号の中で最も有名なのは、シーザー暗号という暗号です。 シーザー暗号とは、ガリア戦争(紀元前58年~紀元前51年にヨーロッパで起こった戦争)において、 古代ローマガイウス・ユリウス・カエサルが使用していた暗号です。 シーザー暗号は「それぞれの文字を3文字ずつずらす」 というとてもシンプルな仕組みで暗号化が可能です。

a b c d e f g h i j k l m n o p q r s t u v w x y z
d e f g h i j k l m n o p q r s t u v w x y z a b c

シーザー暗号は,このような対応表を用いて暗号化していました。「 i am bob」をシーザー暗号で暗号化すると、「L DP ERE」となります。

この時のとはどの知識のことを指すのでしょうか。 それは「3文字右にずらす」という知識です。 この暗号文「L DP ERE」は、「3文字右にずらす」という知識を知らない人には、 ランダムな文字列に見えますが、「3文字右にずらす」という知識を知っている人(鍵を持っている)には、 「i am bob」という情報を伝えることが出来ます(復号する場合には、3文字左にずらせば良い)。

なぜパスワードはハッシュ化されるのか

それでは、本題に戻ります。もし、パスワードを暗号化していたらどのような不都合が生じるでしょうか。 私は、大きく分けて2つあると思います。

  • 鍵の管理
  • 管理者にパスワードを見られてしまう

暗号化には、鍵(特別な知識)が必要となり、それを管理しなければなりません。 しかし、ハッシュ化にはそのようなものは必要ありません。 また、暗号化の場合は、ハッシュ化とは異なり復号することが可能です。 つまり、サイトの管理者など鍵を持っている人には、パスワードがバレてしまうということになります。 顧客などのパスワードを悪用しようとする管理者はいないと思いますが、 理論上それが出来てしまうことが問題なのです。

まとめ

  • 暗号化:情報の伝達 → 元の文字列に戻す必要
  • ハッシュ化:情報の秘匿 → 元の文字列に戻す必要

パスワードは認証さえできれば良いので、ハッシュ化の方が適している。

なぜパスワードを忘れると再設定しなければならないのか

これを読んでいるあなたも一度はパスワードを忘れて再設定をしたことがあるでしょう。「再設定なんて面倒だからパスワード教えてよ」と怒りに震えたこともあるでしょう。では、なぜパスワードを再設定しなければならないのか。それはパスワードがハッシュ化されて保存されているからです。

ハッシュ関数

ハッシュ(hash)とは、「切り刻む」や「細かくする」という意味です。ハッシュ関数とは、任意長のメッセージを入力すると、あたかもランダムであるような固定長の値(ハッシュ値)を出力する特別な関数です。

任意長とは、そのまま「任意の長さ」という意味です。つまり、任意長のメッセージとは、「文字数は何でも良い文字列」ということになります。一方、固定長のメッセージとは、「文字数がある値に固定された文字列」のことです。

ハッシュ化の例

難しそうな言葉ばかりで嫌気が差すと思うので、例を示しましょう。 下の表は、SHA1というハッシュ関数によってハッシュ化された例です。

任意長のメッセージ 固定長のメッセージ
hoge 31F30DDBCB1BF8446576F0E64AA4C88A9F055E3C
hogehoge 3B2C6C10D0E78072D14E02CC4C587814D0F10F3A
hogehogehogehoge 947C3CBB22FDDE06BA8E1460B91C41D5B92FFD0C

「hogehoge」のハッシュ値は、「hoge」のハッシュ値を2つ繋げた値とはなっていないですし、どんな長さのメッセージでも必ず40文字の固定長のメッセージになっていますね!

暗号化との違い

ここまで読んできて「ハッシュ化って暗号化のことじゃないの?」と思われた方もいると思います。実は、ハッシュ化と暗号化は全くの別物です。暗号化とは、元データを復元可能なデータに変換しているのに対して、ハッシュ化は復元不可能なデータに変換しています。

つまり、暗号化は暗号化した後に復号することにより元データを得ることが出来ますが、ハッシュ値からは元データを得ることは出来ません。

20190209220150

パスワードを再設定しなければならない理由

ここでようやく本題に戻ります。パスワードを再設定しなければならない理由は、パスワードがハッシュ化されて保存されているからと冒頭で述べました。つまり、保存されているあなたのパスワードのハッシュ値からあなたのパスワードを知ることは不可能なのです。

まとめ

今回は、パスワードを忘れてしまった時にパスワードを再設定しなければならない理由について書いてみました。「ハッシュ」という知識を持っているだけでなく、このように日常の疑問と紐付けて自分の頭で考えることが勉強の醍醐味ですよね。

本ブログは、『暗号技術のすべて』という本を参考にしました。間違いなど見つけましたら赤子に教えるように優しく教えてください。お願いします。