サンプルコード: データ暗号化アプリケーション

スマートフォンタブレット暗号化

この記事は、インテル® デベロッパー・ゾーンに掲載されている「Sample Code: Data Encryption Application」(http://software.intel.com/en-us/android/articles/sample-code-data-encryption-application) の日本語参考訳です。


サンプルコードのダウンロード

アプリケーション提供元:
インテル コーポレーション SSG

はじめに

第三者にアクセスされたくないデータを安全に保護するには、一般に暗号化を使用します。暗号化は、これまでセキュリティー業界で注目されていましたが、有益な情報がより多くのモバイルデバイスに格納されるにつれて、情報セキュリティーを保証する暗号化がますます重要になっています。

この記事では、Java* または OpenSSL で利用できるデータ暗号化 API を紹介します。いずれのソリューションも Android* OS で動作します。

両方のコードをコンパイルして試してみることを推奨します。

データ暗号化コードと説明

Android* 上のデータを暗号化するには、Java* Crypto API と OpenSSL API の 2 つのオプションがあります。それぞれのオプションについて説明します。

Java* Crypto API

Java* Crypto API は Android* 上で簡単に利用できます。まず、javax.crypto パッケージの KeyGenerator クラスを使用して暗号化用のキーを生成します。

mKey = null;
try {
    kgen = KeyGenerator.getInstance("AES");
    mKey = kgen.generateKey();

} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
}

次に、生成されたキーを用いてデータファイルを暗号化します。バイトのチャンクを javax.crypto で作成した AES Cipher に渡します。

// origFilepath を読み込むストリームを開き、暗号化されたコンテンツを outfile に保存
    InputStream fis = new FileInputStream(origFilepath);
    File outfile = new File(encFilepath);
    int read = 0;
    if (!outfile.exists())
        outfile.createNewFile();

    FileOutputStream encfos = new FileOutputStream(outfile);
    // "AES" プロバイダーを使用して Cipher を作成
    Cipher encipher = Cipher.getInstance("AES");
    encipher.init(Cipher.ENCRYPT_MODE, mKey);
    CipherOutputStream cos = new CipherOutputStream(encfos, encipher); 

    // ファイルを暗号化する時間を計測
    start = System.nanoTime();
    Log.d(TAG, String.valueOf(start)); 

    byte[] block = new byte[mBlocksize]; 

    while ((read = fis.read(block,0,mBlocksize)) != -1) {
        cos.write(block,0, read);
    }
    cos.close();
    stop = System.nanoTime();

    Log.d(TAG, String.valueOf(stop));
    seconds = (stop - start) / 1000000;// ミリ秒
    Log.d(TAG, String.valueOf(seconds));

    fis.close();

OpenSSL API

Android* 上で OpenSSL でデータを暗号化するには、JNI 呼び出しで Java* にアクセスできるネイティブ C コードを記述する必要があります。必要な作業は多くなりますが、より優れたパフォーマンスを得られます。

最初に、キーと初期化ベクトル (iv) を生成します。

unsigned char cKeyBuffer[KEYSIZE/sizeof(unsigned char)];
unsigned char iv[] = "01234567890123456";
int opensslIsSeeded = 0;
if (!opensslIsSeeded) {
    if (!RAND_load_file("/dev/urandom", seedbytes)) {
        return -1;
    }
    opensslIsSeeded = 1;
}

if (!RAND_bytes((unsigned char *)cKeyBuffer, KEYSIZE )) {
}

次に、生成されたキー (cKeyBuffer) を使用してファイルを暗号化します。生成されたキーと初期化ベクトル (iv) を渡して EVP を初期化します。バイトのチャンクを EVP_EncryptUpdate 関数に渡した後、最後のバイトのチャンクを EVP_EncryptFinal_ex 関数に渡します。

if (!(EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, cKeyBuffer, iv ))) {
    ret = -1;
    printf( "ERROR: EVP_ENCRYPTINIT_EXn");
}

// 暗号化するファイルの準備
if ( orig_file != NULL ) {
    origData = new unsigned char[aes_blocksize];
    encData = new unsigned char[aes_blocksize+EVP_CIPHER_CTX_block_size(e_ctx)];
    // 暗号化でオリジナルよりも 16 バイト長くなる可能性がある

    printf( "Encoding file: %sn", filename);

    bytesread = fread(origData, 1, aes_blocksize, orig_file);
    // ファイルからバイトを読み込んで暗号化ルーチンに渡す
    while ( bytesread ) {

        if (!(EVP_EncryptUpdate(e_ctx, encData, &len, origData, bytesread))) {
            ret = -1;
            printf( "ERROR: EVP_ENCRYPTUPDATEn");
            }
            encData_len = len;

            fwrite(encData, 1, encData_len, enc_file );
            // 次のバイトを読み込む
            bytesread = fread(origData, 1, aes_blocksize, orig_file);
    }
    // 暗号化の最終ステップ
    if (!(EVP_EncryptFinal_ex(e_ctx, encData, &len))) {
        ret = -1;
        printf( "ERROR: EVP_ENCRYPTFINAL_EXn");
    }
    encData_len = len;

    fwrite(encData, 1, encData_len, enc_file );

    // 暗号化ルーチンを解放
    EVP_CIPHER_CTX_free(e_ctx);

まとめ

この記事で説明したサンプルのようにコードを実装することで、Java* Crypto API および OpenSSL API を使用して、インテル® プロセッサーを搭載する Android* プラットフォーム上でデータを暗号化する手法を素早く理解できます。

著者紹介

Christopher Bird
インテル コーポレーションのソフトウェア & ソリューション・グループ (SSG) デベロッパー・リレーション部門 インテル® Atom™ プロセッサー・イノベーティブ・テクノロジー・エンジニアリング・チームのメンバー。

著作権と商標について

本資料に掲載されている情報は、インテル製品の概要説明を目的としたものです。本資料は、明示されているか否かにかかわらず、また禁反言によるとよらずにかかわらず、いかなる知的財産権のライセンスを許諾するものではありません。製品に付属の売買契約書『Intel’s Terms and Conditions of Sale』に規定されている場合を除き、インテルはいかなる責任を負うものではなく、またインテル製品の販売や使用に関する明示または黙示の保証 (特定目的への適合性、商品適格性、あらゆる特許権、著作権、その他知的財産権の非侵害性への保証を含む) に関してもいかなる責任も負いません。

インテルによる書面での合意がない限り、インテル製品は、その欠陥や故障によって人身事故が発生するようなアプリケーションでの使用を想定した設計は行われていません。

インテル製品は、予告なく仕様や説明が変更される場合があります。機能または命令の一覧で「留保」または「未定義」と記されているものがありますが、その「機能が存在しない」あるいは「性質が留保付である」という状態を設計の前提にしないでください。これらの項目は、インテルが将来のために留保しているものです。インテルが将来これらの項目を定義したことにより、衝突が生じたり互換性が失われたりしても、インテルは一切責任を負いません。この情報は予告なく変更されることがあります。この情報だけに基づいて設計を最終的なものとしないでください。

本資料で説明されている製品には、エラッタと呼ばれる設計上の不具合が含まれている可能性があり、公表されている仕様とは異なる動作をする場合があります。現在確認済みのエラッタについては、インテルまでお問い合わせください。

最新の仕様をご希望の場合や製品をご注文の場合は、お近くのインテルの営業所または販売代理店にお問い合わせください。

本資料で紹介されている資料番号付きのドキュメントや、インテルのその他の資料を入手するには、1-800-548-4725 (アメリカ合衆国) までご連絡いただくか、
http://www.intel.com/design/literature.htm (英語) を参照してください。

性能に関するテストに使用されるソフトウェアとワークロードは、性能がインテル® マイクロプロセッサー用に最適化されていることがあります。SYSmark* や MobileMark* などの性能テストは、特定のコンピューター・システム、コンポーネント、ソフトウェア、操作、機能に基づいて行ったものです。結果はこれらの要因によって異なります。製品の購入を検討される場合は、他の製品と組み合わせた場合の本製品の性能など、ほかの情報や性能テストも参考にして、パフォーマンスを総合的に評価することをお勧めします。

本資料に含まれるソフトウェア・ソース・コードはソフトウェア・ライセンス契約に基づいて提供されるものであり、その使用および複製はライセンス契約で定められた条件下でのみ許可されます。

Intel、インテル、Intel ロゴ、Intel Atom は、アメリカ合衆国および / またはその他の国における Intel Corporation の商標です。

© 2014 Intel Corporation. 無断での引用、転載を禁じます。

* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。

タイトルとURLをコピーしました