暗号化メッセージの送信

受信者アカウントでしか読めない暗号化メッセージを送信します。

ユースケース

Alice が自分の学業証明書を表すアカウントに機密なメッセージへタイムスタンプを付けて送信しようとしているとイメージしてください。

Alice はパブリックネットワークへ 平文メッセージ の付いた TransferTransaction を送信すると、メッセージの内容を公にすることを理解しています。

そのため、Alice は自分自身と学術証明書へのアクセス権を持つものだけが読めるように 暗号化メッセージ を送ります。

前提条件

ユースケースのセットアップ

新しいアカウントを2つ作成する: Alice と証明書用アカウントを CLI ツール を使用して作成します。

symbol-cli account generate --save

Enter network type (MIJIN_TEST, MIJIN, MAIN_NET, TEST_NET): TEST_NET
Do you want to save it? [y/n]: y
Enter a Symbol Node URL. (Example: http://localhost:3000): http://api-01.us-east-1.testnet.symboldev.network:3000/
Insert profile name: alice
symbol-cli account generate --save

Enter network type (MIJIN_TEST, MIJIN, MAIN_NET, TEST_NET): TEST_NET
Do you want to save it? [y/n]: y
Enter a Symbol Node URL. (Example: http://localhost:3000): http://api-01.us-east-1.testnet.symboldev.network:3000/
Insert profile name: certificate

方法 #01: SDK を使用する

メッセージの暗号化

  1. 証明書用の 暗号化メッセージ を作成して Alice のアカウントで署名します。
  const networkType = await repositoryFactory.getNetworkType().toPromise();
  // replace with alice private key
  const alicePrivateKey =
    '1111111111111111111111111111111111111111111111111111111111111111';
  const aliceAccount = Account.createFromPrivateKey(
    alicePrivateKey,
    networkType,
  );
  // replace with certificate public key
  const certificatePublicKey =
    '3A537D5A1AF51158C42F80A199BB58351DBF3253C4A6A1B7BD1014682FB595EA';
  const certificatePublicAccount = PublicAccount.createFromPublicKey(
    certificatePublicKey,
    networkType,
  );

  const encryptedMessage = aliceAccount.encryptMessage(
    'This message is secret',
    certificatePublicAccount,
  );
  const networkType = await repositoryFactory.getNetworkType().toPromise();
  // replace with alice private key
  const alicePrivateKey =
    '1111111111111111111111111111111111111111111111111111111111111111';
  const aliceAccount = symbol_sdk_1.Account.createFromPrivateKey(
    alicePrivateKey,
    networkType,
  );
  // replace with certificate public key
  const certificatePublicKey =
    '3A537D5A1AF51158C42F80A199BB58351DBF3253C4A6A1B7BD1014682FB595EA';
  const certificatePublicAccount = symbol_sdk_1.PublicAccount.createFromPublicKey(
    certificatePublicKey,
    networkType,
  );
  const encryptedMessage = aliceAccount.encryptMessage(
    'This message is secret',
    certificatePublicAccount,
  );
  1. TransferTransaction に暗号化メッセージを添付して、受信者には証明書アドレスを設定します。
  const transferTransaction = TransferTransaction.create(
    Deadline.create(epochAdjustment),
    certificatePublicAccount.address,
    [],
    encryptedMessage,
    networkType,
    UInt64.fromUint(2000000),
  );
  const transferTransaction = symbol_sdk_1.TransferTransaction.create(
    symbol_sdk_1.Deadline.create(epochAdjustment),
    certificatePublicAccount.address,
    [],
    encryptedMessage,
    networkType,
    symbol_sdk_1.UInt64.fromUint(2000000),
  );
  1. Alice のアカウントでトランザクションに署名します。

注釈

自分のネットワークでのみ有効なトランザクションを作るには、ネットワークジェネレーションハッシュを含めます。新しいブラウザタブで nodeUrl + '/node/info' を開いて meta.networkGenerationHash の値をコピーします。

  const networkGenerationHash = await repositoryFactory
    .getGenerationHash()
    .toPromise();
  const signedTransaction = aliceAccount.sign(
    transferTransaction,
    networkGenerationHash,
  );
  console.log(signedTransaction.hash);
  const networkGenerationHash = await repositoryFactory
    .getGenerationHash()
    .toPromise();
  const signedTransaction = aliceAccount.sign(
    transferTransaction,
    networkGenerationHash,
  );
  console.log(signedTransaction.hash);
  1. 署名したら トランザクションをネットワークへアナウンス できます。
  const transactionRepository = repositoryFactory.createTransactionRepository();

  const response = await transactionRepository
    .announce(signedTransaction)
    .toPromise();
  console.log(response);
  const transactionRepository = repositoryFactory.createTransactionRepository();
  const response = await transactionRepository
    .announce(signedTransaction)
    .toPromise();
  console.log(response);

メッセージの復号

トランザクションが承認された後に (3) で出力されたトランザクションハッシュを使用してトランザクションを取得します。証明書アカウントまたはアドレスアカウントを使用して メッセージを復号 できます。

// replace with network type
const networkType = NetworkType.TEST_NET;

// replace with certificate private key
const certificatePrivateKey =
  'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
const certificateAccount = Account.createFromPrivateKey(
  certificatePrivateKey,
  networkType,
);
// replace with alice public key
const alicePublicKey =
  'D04AB232742BB4AB3A1368BD4615E4E6D0224AB71A016BAF8520A332C9778737';
const alicePublicAccount = PublicAccount.createFromPublicKey(
  alicePublicKey,
  networkType,
);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.testnet.symboldev.network:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
// replace with transaction hash
const transactionHash =
  '0000000000000000000000000000000000000000000000000000000000000000';

transactionHttp
  .getTransaction(transactionHash, TransactionGroup.Confirmed)
  .pipe(map((x) => x as TransferTransaction))
  .subscribe(
    (transaction) => {
      console.log('Raw message: ', transaction.message.payload);
      console.log(
        'Message: ',
        certificateAccount.decryptMessage(
          transaction.message,
          alicePublicAccount,
        ).payload,
      );
    },
    (err) => console.log(err),
  );
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
// replace with certificate private key
const certificatePrivateKey =
  'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
const certificateAccount = symbol_sdk_1.Account.createFromPrivateKey(
  certificatePrivateKey,
  networkType,
);
// replace with alice public key
const alicePublicKey =
  'D04AB232742BB4AB3A1368BD4615E4E6D0224AB71A016BAF8520A332C9778737';
const alicePublicAccount = symbol_sdk_1.PublicAccount.createFromPublicKey(
  alicePublicKey,
  networkType,
);
// replace with node endpoint
const nodeUrl = 'http://api-01.us-east-1.testnet.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
// replace with transaction hash
const transactionHash =
  '0000000000000000000000000000000000000000000000000000000000000000';
transactionHttp
  .getTransaction(transactionHash, symbol_sdk_1.TransactionGroup.Confirmed)
  .pipe(operators_1.map((x) => x))
  .subscribe(
    (transaction) => {
      console.log('Raw message: ', transaction.message.payload);
      console.log(
        'Message: ',
        certificateAccount.decryptMessage(
          transaction.message,
          alicePublicAccount,
        ).payload,
      );
    },
    (err) => console.log(err),
  );

メッセージを読むことができたら、定義された参加者だけが暗号化された内容を読むことができることを確認するために、別の無関係なアカウントを使ってメッセージが解読できないことを試してください。