Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@nem_takanobu

NEMアカウントを作ろう!2

More than 1 year has passed since last update.

前回はブラウザを使って簡単にNEMアカウントを作る方法を解説しました。

今回はもう少し強度の高い秘密鍵の生成に挑戦します。
まず、乱数ですが擬似乱数と明確に区別する必要があります。

擬似乱数とは大雑把な言い方をすると、乱数表というものの中から適当に数字を取ってくるような感じです。ですのでシード値と呼ばれるものを指定すれば、かならず同じ値が手に入ります。

そうです、Math.random() のような関数で擬似乱数で秘密鍵を作ってはいけません!

では完全にランダムな乱数というものは作れるのでしょうか?
実はこれも不可能です。システムは何かしらのインプットをたよりに乱数を作ることしかできません。
なので、そのインプット値をコピーされれば同じ乱数値を再現することは可能です。
ですので、限りなくランダムに近い値を目指すしかないのです。
しかし、そのブラウザが十分にランダムなつもりではじき出した乱数も
近い将来その仕組みが解明されて再現方法が見つかってしまうかもしれません。

そのときに重要なキーワードとなるのがエントロピーという概念です。

ルービックキューブを思い浮かべてください。
何回か縦横に回されたルービックキューブは子供が偶然触ったぐらいでは元に戻せなくなります。
そして十分にぐちゃぐちゃにされたされたルービックキューブは大の大人でも元に戻すのは相当困難になるでしょう。

この原理で、秘密鍵を作成するときもランダムに生成した乱数をさらにぐちゃぐちゃにかき回して、
ブラウザが作りだした乱数をさらに復元不可能なものに変換させます。

前回同様HTMLは以下の通り

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>

    <!-- ライブラリ -->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
    <script src="nacl-fast.js"></script>
    <script src="xembook-sdk.js"></script>

    <!-- app -->
    <script>
//ここにロジックを追加していきます

    </script>
  </body>
</html>

挿入するロジックは少し追加して以下の通りです。


let r = ua2hex(nacl.randomBytes(32));
let seed = processEntropy("0124595587184571048560847563487523487394857234057", "password");
let privateKey = derivePassSha(r + seed, 1000).priv;
let k = KeyPair.create(privateKey);
let address = toAddress(k.publicKey.toString(), 104);

processEntropyを使用して、エントロピーとパスワードからシード値を生成します。
パスワードとはNanoWalletの場合、ログインパスワードを指しますが、今回はなんでもよいです。
そして、"0124595587184571048560847563487523487394857234057"というのがエントロピー値です。
この値が複雑であれば複雑であるほど、復元困難となります。

そして、導出されたシード値と乱数を足し合してさらに1000回グチャグチャにしたものを秘密鍵とします。
後は前回と同様にKeyPairを生成して公開鍵とアドレスを出力すればNEMアカウントセットの出来上がりです。

これで十分に強度の高いNEMアカウントを作成できました。
ちょっと説明が漏れてますね。今回固定値で指定したエントロピー値にはどういったものが適切でしょうか?
NanoWalletでアカウントを作成した人ならわかると思いますが、
マウス操作によって出力される座標値移動情報などは再現できる可能性が低く、よく利用される方法です。
(今回例示した数値列は明らかに桁数が少ないのでご注意ください)

またおいおい追加していきますので、ぜひご参考ください。

1
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
nem_takanobu
ブロックチェーンはNEM、機械学習はPyTorchが好きです。最近はガウス過程(MCMC、GPLVM)を勉強中。経産省・IPA認定ITストラテジスト

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?