あるSEのつぶやき・改

ITやシステム開発などの技術に関する話題を、取り上げたりしています。

React NativeでユーザーIDとパスワードを安全な場所に保存する

はじめに

React Native でユーザーIDとパスワードを安全に保存したいというニーズはよくあると思います。

但し、スマートフォンのアプリで普通に重要情報を保存してしまうと、他のアプリや攻撃者から読み取られてしまう危険性があります。

この問題を回避するために、iOS では KeyChain、Android では KeyStore という安全に重要情報を保存できる場所が用意されています。

この KeyChain と KeyStore に、React Native からユーザーIDとパスワードを保存する方法をご紹介します。

使用するライブラリ

iOS では KeyChain、Android では KeyStore にユーザーIDとパスワードを保存するために、 react-native-keychainというライブラリを使用します。

また、ログに OS 情報を出力するために、react-native-device-infoというライブラリも使用します。

プロジェクトの作成

React Native のプロジェクトを作成します。今回は TypeScript を使用するので、以下のようにコマンドを実行します。

$ npx react-native init KeySecure --template react-native-template-typescript

インストール

下記コマンドを実行して、必要なライブラリをインストールします。

$ yarn add react-native-keychain
$ yarn add react-native-device-info
$ cd ios && pod install && cd ..

App.tsx の編集

App.tsxを以下のように編集します。

内容は見てのとおりですが、ユーザーIDとパスワードを KeyChain/KeyStore に保存したあと、保存した内容を取得し、最後に削除します。ユーザーIDとパスワードを取得した際、ログに内容を出力しています。

import React, {useEffect} from 'react';
import {SafeAreaView, Text} from 'react-native';
import * as Keychain from 'react-native-keychain';
import DeviceInfo from 'react-native-device-info';

const App = () => {
  useEffect(() => {
    const storeKey = async () => {
      const username = 'zuck';
      const password = 'poniesRgr8';

      // Retrieve the systemname
      const systemName = DeviceInfo.getSystemName();
      console.log(systemName);

      // Store the credentials
      await Keychain.setGenericPassword(username, password);

      try {
        // Retrieve the credentials
        const credentials = await Keychain.getGenericPassword();
        if (credentials) {
          console.log(
            'Credentials successfully loaded for user ' + credentials.username,
          );
          console.log(
            'Credentials successfully loaded for password ' +
              credentials.password,
          );
        } else {
          console.log('No credentials stored');
        }
      } catch (error) {
        console.log("Keychain couldn't be accessed!", error);
      }

      // Remove the credentials
      await Keychain.resetGenericPassword();
    };

    storeKey();
  }, []);

  return (
    <>
      <SafeAreaView>
        <Text>Hello</Text>
      </SafeAreaView>
    </>
  );
};

export default App;

実行

iOS で動作させるために、下記コマンドを実行します。

$ npx react-native run-ios

ログが正しく出力されることが分かります。

f:id:fnyablog:20200320162600p:plain:w640

なお、iOS でログが出力されない場合は、下記記事を参考にしてください。

www.aruse.net

Android で動作させるために、下記コマンドを実行します。

$ npx react-native run-android

こちらも、ログが正しく出力されることが分かります。

f:id:fnyablog:20200320162828p:plain:w640

おわりに

なかなか苦戦させられましたが、なんとかユーザーIDとパスワードを安全な場所に保存する方法が分かりました。

但し、react-native-keychainはユーザーIDとパスワードの一組しか保存できないため、任意のキーや、複数のキーを保存するには他の方法で行う必要があります。

参考サイト

blog.jscrambler.com