SlideShare a Scribd company logo
1 of 69
Download to read offline
C-LIS CO., LTD.
自己紹介
Android Studio本
3
2014年11月21日発売
技術評論社刊
Android Studio 0.8.6
http://amzn.to/1HYRp32
4
5
https://github.com/keiji/the-androidstudio-book
コミックマーケット87

Android Studioセットアップガイド
6
https://anharu.keiji.io
はじめての
Androidアプリ開発レッスン
7
改訂版が出ます(2016年1月上旬予定)
改訂版の原稿を送ったのが11月16日
9
11月20日
サンプルコードのプロジェクトを

Android 1.5用に調整したのが11月23日
11月24日
11
Android Studio 2.0 Preview
続く
Realmの暗号化と

Android System
2015/11/25 Realm Meetup #9
今日の内容
データの保護
15
 ユーザーや悪意のある開発者からデータを保護したい。
 安全にデータを保管するための方法として

「javax.cryptoによるデータベースファイルの保護」

「SQLCipherを使った保護」

「Realmの暗号化機能」

 の、三つについて、それぞれ利用して比較する。
鍵の保護
16
 暗号化したデータの復号鍵をどこに保存するかは大きな
課題である。
 Android 6.0で大幅に強化された「Android Keystore
System」を使って、データを安全に保護する方策を検討
する。
 
データの保護を検討する
https://github.com/keiji/realm_meetup_9/releases/tag/realm_meetup_9
{

"characters": [

{

"name": "Uduki Shimamura",

"age": "17",

"megane": false

},

{

"name": "Rin Shibuya",

"age": "15",

"megane": false

},

{

"name": "Haruna Kamijo",

"age": "18",

"megane": true

},
サンプルアプリ
18
https://github.com/keiji/realm_meetup_9/releases/tag/realm_meetup_9
アプリの動作
https://github.com/keiji/realm_meetup_9/releases/tag/realm_meetup_9
{

"characters": [

{

"name": "Uduki Shimamura",

"age": "17",

"megane": false

},

{

"name": "Rin Shibuya",

"age": "15",

"megane": false

},

{

"name": "Mio Honda",

"age": "15",

"megane": false

},

{

"name": "Hina Araki",

"age": "20",

"megane": false

},

characters.json
Database
ユーザー
検索 &
一覧表示
JSONパース
保存
19
検索条件
{

"characters": [

{

"name": "Uduki Shimamura",

"age": "17",

"megane": false

},

{

"name": "Rin Shibuya",

"age": "15",

"megane": false

},

{

"name": "Haruna Kamijo",

"age": "18",

"megane": true

},
これがtrue
https://github.com/keiji/realm_meetup_9/releases/tag/realm_meetup_9
20
実行画面
21
javax.crypto
22
•Androidに組み込まれている暗号化フレームワーク
•AES 256-bitに対応している
暗号化したデータベースファイルを、
利用時に限定して復号する
@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);



setContentView(R.layout.user_list);

mListView = (ListView) findViewById(R.id.listview);



getSupportLoaderManager().restartLoader(LOADER_ID_DECRYPT, null, mCipherLoaderCallback);

}



@Override

protected void onDestroy() {

super.onDestroy();



mDb.close();



new EncryptTask(getDatabasePath(DbHelper.DB_FILE_NAME)).execute();

}
sqlite.SQLiteActivity
23
private static final String TRANSFORMATION = "AES/CBC/PKCS7Padding";

private static final byte[] KEY = "thisismypa55w0rdthisismypa55w0rd".getBytes();

sqlite.SQLiteActivity
24
SecretKeySpec key = new SecretKeySpec(KEY, "AES");



Cipher cipher = Cipher.getInstance(TRANSFORMATION);

cipher.init(Cipher.ENCRYPT_MODE, key);



byte[] buffer = new byte[cipher.getBlockSize()];

int len;



while ((len = is.read(buffer)) != -1) {

byte[] encrypted = cipher.update(buffer, 0, len);

os.write(encrypted);

}

os.write(cipher.doFinal());



rawDbFile.deleteOnExit();
32byte必要
テーブル構造
25
private static final String CREATE_TABLE_USERS = "CREATE TABLE characters ( " +

"_id INTEGER PRIMARY KEY," +

"name TEXT," +

"age INTEGER," +

"megane INTEGER" +

" )";

public static Character read(Cursor cursor) {

Character user = new Character();

user.name = cursor.getString(cursor.getColumnIndex("name"));

user.age = cursor.getInt(cursor.getColumnIndex("age"));

user.megane = cursor.getInt(cursor.getColumnIndex("megane")) == 1;

return user;

}



public static Cursor findAllMeganeCursor(SQLiteDatabase db) {

return db.query("characters", new String[]{"_id", "name", "age", "megane"},

"megane = ?", new String[]{Integer.toString(1)}, null, null, null);

}

sqlite.DbHelper.java
sqlite.entity.Character.java
問題点
26
復号してデータベースにアクセスしている間、

暗号化されていないデータがファイルシステム上に存在する
SQLCipher
27
•Zetetic社が開発、提供する暗号化機能付きSQLite
•AES 256-bitで暗号化
•透過的にアクセス可能
暗号化したままデータを読み書きする
公式ではバイナリを配布せず
28
SQLCipherは、基本的に有償版を推しているイメージ。
オープンソース版のCommunity Editionは個々でビルドする
dependencies {

compile fileTree(dir: 'libs', include: ['*.jar'])

testCompile 'junit:junit:4.12'

compile 'com.android.support:appcompat-v7:23.1.1'

compile 'net.zetetic:android-database-sqlcipher:3.3.1-2'



}

BintrayでAndroid版を入手
app/build.gradle
29
private static final String DB_PASSWORD = "pa55w0rd";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);



SQLiteDatabase.loadLibs(this);



setContentView(R.layout.user_list);

mListView = (ListView) findViewById(R.id.listview);



if (!getDatabasePath(DbHelper.DB_FILE_NAME).exists()) {

mDb = new DbHelper(this).getWritableDatabase(DB_PASSWORD);

getSupportLoaderManager().restartLoader(LOADER_ID, null, mLoaderCallback);

sqlcipher.SQLCipherActivity
30
テーブル構造
31
private static final String CREATE_TABLE_USERS = "CREATE TABLE characters ( " +

"_id INTEGER PRIMARY KEY," +

"name TEXT," +

"age INTEGER," +

"megane INTEGER" +

" )";

public static Character read(Cursor cursor) {

Character user = new Character();

user.name = cursor.getString(cursor.getColumnIndex("name"));

user.age = cursor.getInt(cursor.getColumnIndex("age"));

user.megane = cursor.getInt(cursor.getColumnIndex("megane")) == 1;

return user;

}



public static Cursor findAllMeganeCursor(SQLiteDatabase db) {

return db.query("characters", new String[]{"_id", "name", "age", "megane"},

"megane = ?", new String[]{Integer.toString(1)}, null, null, null);

}

sqlcipher.DbHelper.java
sqlcipher.entity.Character.java
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[
DexPathList[
[zip file "/data/app/io.keiji.realmsample2-2/base.apk"],
nativeLibraryDirectories=[/data/app/io.keiji.realmsample2-2/lib/arm64,
/data/app/io.keiji.realmsample2-2/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]]
couldn't find "libstlport_shared.so"
at java.lang.Runtime.loadLibrary(Runtime.java:367)
at java.lang.System.loadLibrary(System.java:1076)
at net.sqlcipher.database.SQLiteDatabase.loadLibs(SQLiteDatabase.java:173)
at net.sqlcipher.database.SQLiteDatabase.loadLibs(SQLiteDatabase.java:169)
at io.keiji.realmsample2.sqlcipher.SQLCipherActivity.onCreate(SQLCipherActivity.java:83)
at android.app.Activity.performCreate(Activity.java:6237)
Android 6.0(Marshmallow)
32
問題点
33
SQLCipherのSQLiteDatabaseクラスは、

net.sqlcipher.databaseパッケージに所属している。
SQLiteDatabaseとの継承関係もないため、

一般的なORMとの相性は良くないと思われる
Realm
34
•Realm社が開発、提供するNoSQLデータベース
•AES 256-bitで暗号化
•透過的にアクセス可能
読み書き中もデータは暗号化されたまま
データが抜き出されても現実的な時間では解読が困難
public class RealmAdapter {



private static final byte[] KEY
= "thisismypa55w0rdthisismypa55w0rdthisismypa55w0rdthisismypa55w0rd".getBytes();



public RealmConfiguration getRealmConfiguration(Context context) {

return new RealmConfiguration.Builder(context)

.encryptionKey(KEY)

.build();

}

}
 64byte必要
@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);



setContentView(R.layout.user_list);



mRealmAdapter = new RealmAdapter();



mRealm = Realm.getInstance(mRealmAdapter.getRealmConfiguration(this));



realm.RealmActivity
35
RealmResults<Character> realmResult = mRealm

.where(Character.class)

.equalTo("megane", true)

.findAll();

mListView = (ListView) findViewById(R.id.listview);

mAdapter = new Adapter(this, realmResult, true);

mListView.setAdapter(mAdapter);

情報を検索して表示
public class Adapter extends RealmBaseAdapter<Character> {



@Override

public View getView(int position, View convertView, ViewGroup parent) {

Character character = getItem(position);



ViewHolder holder = null;

if (convertView == null) {

convertView = View.inflate(RealmActivity.this, R.layout.user_list_row, null);

holder = new ViewHolder((TextView) convertView.findViewById(R.id.label));

convertView.setTag(holder);

}

36
遭遇した課題
createObjectFromJson
38
{

"characters": [

{

"name": "Uduki Shimamura",

"age": "17",

"megane": false

},

{

"name": "Rin Shibuya",

"age": "15",

"megane": false

},

{

"name": "Haruna Kamijo",

"age": "18",

"megane": true

},
public class Character extends RealmObject {



private long id;



private String name;



private Integer age;



private boolean megane = true;

public class Characters extends RealmObject {



private RealmList<Character> characters;

createObjectFromJson
39
public class JsonLoaderRealmJson extends AsyncTaskLoader<LoaderResult> {

@Override

public LoaderResult loadInBackground() {



LoaderResult result;



Realm realm = Realm.getInstance(realmAdapter.getRealmConfiguration(getContext()));



try {



realm.beginTransaction();

realm.createObjectFromJson(Characters.class, getContext().getAssets().open(JSON_FILE_NAME));

realm.commitTransaction();



result = new LoaderResult(null);



} catch (IOException e) {

想定していないデータの存在
40
{

"name": "Kirari Moroboshi",

"age": "17",

"megane": false

},

{

"name": "Nana Abe",

"age": "永遠の17歳",

"megane": false

},

{

"name": "Akiha Ikebukuro",

"age": "14",

"megane": true

}

]

public class Character extends RealmObject {



private long id;



private String name;



private Integer age;



private boolean megane = true;

public class Characters extends RealmObject {



private RealmList<Character> characters;

課題の解決 - JPP
41
JsonPullParser

https://github.com/vvakame/JsonPullParser

を導入して、Jsonのパース処理をRealmから切り離した。
参考: RealmとJSONライブラリ by zaki50
https://speakerdeck.com/zaki50/realmtojsonraiburari
課題の解決
42
@JsonModel

public class Characters4Jpp {



@JsonKey

private List<Character> characters;



public List<Character> getCharacters() {

return characters;

}



public void setCharacters(List<Character> characters) {

this.characters = characters;

}

}

converterを指定
43
@JsonModel

public class Character extends RealmObject {



@JsonKey

private long id;



@JsonKey

private String name;



@JsonKey(converter = AgeTokenConverter.class)

private Integer age;



@JsonKey

private boolean megane = true;

converter
44
public class AgeTokenConverter extends TokenConverter<Integer> {



static AgeTokenConverter converter = null;



public static AgeTokenConverter getInstance() {

if (converter == null) converter = new AgeTokenConverter();



return converter;

}



@Override

public Integer parse(JsonPullParser parser, OnJsonObjectAddListener listener)
throws IOException, JsonFormatException {

Integer value = null;

if (parser.getEventType() == JsonPullParser.State.VALUE_STRING) {

String str = parser.getValueString();

try {

value = !TextUtils.isEmpty(str) ? Integer.parseInt(str) : null;

} catch (NumberFormatException e) {

}

}



return value;

鍵の保護を検討する
鍵をどこに置く?
46
private static final String DB_PASSWORD = "pa55w0rd";
private static final byte[] KEY
= "thisismypa55w0rdthisismypa55w0rdthisismypa55w0rdthisismypa55w0rd".getBytes();
private static final byte[] KEY = "thisismypa55w0rdthisismypa55w0rd".getBytes();

Android Keystore System
47
 Android端末のセキュリティ・ハードウェア(Secure Element,
Trusted Execution Environment)内に鍵情報を格納する。
 Android 4.3から導入されていたがAndroid 6.0(Marshmallow)で
AES共通鍵に対応するなど機能が強化された。
http://developer.android.com/intl/ja/training/articles/keystore.html
Android Keystore System
48
 javax.cryptoと密接に連携している。
 任意の情報を保存できるわけではない(=Realmの暗号化キーを直
接保存できない)。
http://developer.android.com/intl/ja/training/articles/keystore.html
Android Keystore System
49
Realm暗号キー
64bytes
Android
Keystore
System
鍵情報
AES
暗号キー
64bytes
暗号化済
ユーザー認証
Storage
http://developer.android.com/intl/ja/training/articles/keystore.html
realm_with_ask.RealmActivity
50
static final String PROVIDER_NAME = "AndroidKeyStore";

static final String KEY_ALIAS = "auth_key";
private static void generateKey() {

try {

KeyGenerator keyGenerator = KeyGenerator.getInstance(

KeyProperties.KEY_ALGORITHM_AES,

PROVIDER_NAME);



keyGenerator.init(new KeyGenParameterSpec.Builder(

KEY_ALIAS,

KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)

.setBlockModes(KeyProperties.BLOCK_MODE_CBC)

.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)

.setUserAuthenticationRequired(true)

.setUserAuthenticationValidityDurationSeconds(

AUTH_VALID_DURATION_IN_SECOND)

.build());

keyGenerator.generateKey();



} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException

realm_with_ask.RealmActivity
51
void authorize() {

KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);

Intent intent = km.createConfirmDeviceCredentialIntent("Android Keystore System",

"Android Keystore Systemに保存した を使ってRealmのデータベースにアクセスします");



startActivityForResult(intent, REQUEST_CREDENTIAL);

}

realm_with_ask.RealmActivity
52
realm_with_ask.RealmActivity
53
void readyRealm() {

try {

Cipher cipher = Cipher.getInstance(TRANSFORMATION);



byte[] encryptedKey = null;



File file = new File(getFilesDir(), KEY_FILE_NAME);
// 暗号化された 情報の読み込み → encryptedKey



RealmAdapter.setKey(decryptRealmKey(encryptedKey, cipher));

realm_with_ask.RealmActivity
54
byte[] encryptRealmKey(byte[] passkey, Cipher cipher) {



try {

SecretKey key = (SecretKey) mKeyStore.getKey(KEY_ALIAS, null);

cipher.init(Cipher.ENCRYPT_MODE, key);



byte[] encrypted = cipher.doFinal(passkey);

byte[] initializationVector = cipher.getIV();



byte[] result = new byte[initializationVector.length + encrypted.length];

System.arraycopy(initializationVector, 0, result, 0, initializationVector.length);

System.arraycopy(encrypted, 0, result, initializationVector.length, encrypted.length);



return result;
Initialization Vector
16 bytes
encryption key
64 bytes
realm_with_ask.RealmActivity
55
byte[] decryptRealmKey(byte[] encrypted, Cipher cipher) {

byte[] initializationVector = new byte[16];

byte[] passKey = new byte[encrypted.length - initializationVector.length];



System.arraycopy(encrypted, 0, initializationVector, 0, initializationVector.length);

System.arraycopy(encrypted, initializationVector.length, passKey, 0, passKey.length);



try {

SecretKey key = (SecretKey) mKeyStore.getKey(KEY_ALIAS, null);



IvParameterSpec ivSpec = new IvParameterSpec(initializationVector);

cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);



return cipher.doFinal(passKey);

Fingerprint API
56
 Android 6.0(Marshmallow)で追加。
 Android Keystore Systemをパターンロック・パスワードに
加えて指紋スキャナーで認証する。
http://developer.android.com/intl/ja/about/versions/marshmallow/android-6.0.html#fingerprint-authentication
RealmFingerprintActivity
57
private final AuthenticationCallback mAuthenticationCallback
= new FingerprintManager.AuthenticationCallback() {

@Override

public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {

super.onAuthenticationSucceeded(result);

readyRealm();

}

};

RealmFingerprintActivity
58
@Override
void authorize() {

FingerprintManager fingerprintManager
= (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);



try {

SecretKey key = (SecretKey) mKeyStore.getKey(KEY_ALIAS, null);



Cipher cipher = Cipher.getInstance(TRANSFORMATION);

cipher.init(Cipher.ENCRYPT_MODE, key);



FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);



Toast.makeText(this, "指紋スキャナーに指を当てて下さい...", Toast.LENGTH_LONG)

.show();



//noinspection ResourceType

fingerprintManager.authenticate(cryptoObject, null, 0, mAuthenticationCallback, null);
RealmFingerprintActivity
59
今日の内容 - まとめ
今日の内容 - まとめ
61
 安全にデータを保管するための方法として
「javax.cryptoによるデータベースファイルの保護」
「SQLCipherを使った保護」

「Realmの暗号化機能」
 の3パターンを、それぞれ比較した。
今日の内容 - まとめ
62
 「javax.cryptoによるデータベースファイルの保護」で
は、SQLDatabaseのファイルを必要なときだけ復号し
た。
 しかし、読み書きの最中はファイルシステム上に復号し
たデータファイルが存在するため、安全とは言えなかった。
今日の内容 - まとめ
63
 「SQLCipherを使った保護」では、SQLDatabaseのファ
イルを暗号化した上で全体を復号することなく、透過的に
読み書きができた。
 しかし、Android 6.0で正常な動作が確認できなかった。
また、そのままではActiveAndroidなどORMを適用しに
くいという課題もあった。
今日の内容 - まとめ
64
 Realmを使うと、データベースを暗号で保護した状態
で、透過的に扱うことができた。
 JSONからモデルに変換する機能は、異常値が含まれる
場合などは対応しきれないケースは、JsonPullParserの
converterを使って解決した。
 
今日の内容 - まとめ
65
 「Android Keystore System」を使うことで、機密
データの復号鍵をセキュリティ・ハードウェアに保護され
た領域に保存して、安全に格納することができる。
 ただし、Realmはjavax.crypto.Cipherを直接扱えない
ため、暗号化に用いるキーをAndroid Keystore System
を用いて暗号化。キーをファイルシステムに保存した。
C-LIS CO., LTD.
各製品名・ブランド名、会社名などは、一般に各社の商標または登録商標です。本資料中では、©、®、™を割愛しています。
本資料は、有限会社シーリスの著作物です。掲載されているイラストは、特に記載がない場合は根雪れいの著作物です。
本資料の全部、または一部について、著作者から文書による許諾を得ずに複製することは禁じられています。
Material Icons are reproduced or modified from work created and shared by Google and used according to
terms described in the Creative Commons 4.0 Attribution license.
http://techbooster.github.io/c89/
Copyright TechBooster
C89 - TechBooster 3日目東シ58a
Copyright TechBooster
C89 - TechBooster 3日目東シ58a
Copyright TechBooster

More Related Content

What's hot

AWSとReactで始めるShopifyアプリ開発
AWSとReactで始めるShopifyアプリ開発AWSとReactで始めるShopifyアプリ開発
AWSとReactで始めるShopifyアプリ開発Takaaki Kurasawa
 
コンテナで始める柔軟な AWS Lambda 生活
コンテナで始める柔軟な AWS Lambda 生活コンテナで始める柔軟な AWS Lambda 生活
コンテナで始める柔軟な AWS Lambda 生活Drecom Co., Ltd.
 
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例sairoutine
 
Fargate起動歴1日の男が語る運用の勘どころ
Fargate起動歴1日の男が語る運用の勘どころFargate起動歴1日の男が語る運用の勘どころ
Fargate起動歴1日の男が語る運用の勘どころYuto Komai
 
Photon Fusionのはじめの一歩
Photon Fusionのはじめの一歩Photon Fusionのはじめの一歩
Photon Fusionのはじめの一歩聡 大久保
 
決済サービスの監視を支えるElastic Stack
決済サービスの監視を支えるElastic Stack決済サービスの監視を支えるElastic Stack
決済サービスの監視を支えるElastic StackJunya Suzuki
 
CircleCI vs. CodePipeline
CircleCI vs. CodePipelineCircleCI vs. CodePipeline
CircleCI vs. CodePipelineHonMarkHunt
 
Azure Blob Storageへの様々なアクセス方法を比べてみた JAZUG12周年イベント
Azure Blob Storageへの様々なアクセス方法を比べてみた JAZUG12周年イベントAzure Blob Storageへの様々なアクセス方法を比べてみた JAZUG12周年イベント
Azure Blob Storageへの様々なアクセス方法を比べてみた JAZUG12周年イベントShingo Kawahara
 
アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~gree_tech
 
なぜOpenID Connectが必要となったのか、その歴史的背景
なぜOpenID Connectが必要となったのか、その歴史的背景なぜOpenID Connectが必要となったのか、その歴史的背景
なぜOpenID Connectが必要となったのか、その歴史的背景Tatsuo Kudo
 
JJUG CCC リクルートの Java に対する取り組み
JJUG CCC リクルートの Java に対する取り組みJJUG CCC リクルートの Java に対する取り組み
JJUG CCC リクルートの Java に対する取り組みRecruit Technologies
 
FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術dena_study
 
[Container Runtime Meetup] runc & User Namespaces
[Container Runtime Meetup] runc & User Namespaces[Container Runtime Meetup] runc & User Namespaces
[Container Runtime Meetup] runc & User NamespacesAkihiro Suda
 
Azure Media Services 大全
Azure Media Services 大全Azure Media Services 大全
Azure Media Services 大全Daiyu Hatakeyama
 
Spring Boot + Netflix Eureka
Spring Boot + Netflix EurekaSpring Boot + Netflix Eureka
Spring Boot + Netflix Eureka心 谷本
 
AWS Black Belt Online Seminar 2016 Amazon EC2 Container Service
AWS Black Belt Online Seminar 2016 Amazon EC2 Container ServiceAWS Black Belt Online Seminar 2016 Amazon EC2 Container Service
AWS Black Belt Online Seminar 2016 Amazon EC2 Container ServiceAmazon Web Services Japan
 
[Cloud OnAir] クラウドからエッジまで!進化する GCP の IoT サービス 2018年11月22日 放送
[Cloud OnAir]  クラウドからエッジまで!進化する GCP の IoT サービス 2018年11月22日 放送[Cloud OnAir]  クラウドからエッジまで!進化する GCP の IoT サービス 2018年11月22日 放送
[Cloud OnAir] クラウドからエッジまで!進化する GCP の IoT サービス 2018年11月22日 放送Google Cloud Platform - Japan
 
WebブラウザでC#実行 WebAssemblyの技術
WebブラウザでC#実行 WebAssemblyの技術WebブラウザでC#実行 WebAssemblyの技術
WebブラウザでC#実行 WebAssemblyの技術Sho Okada
 

What's hot (20)

AWSとReactで始めるShopifyアプリ開発
AWSとReactで始めるShopifyアプリ開発AWSとReactで始めるShopifyアプリ開発
AWSとReactで始めるShopifyアプリ開発
 
コンテナで始める柔軟な AWS Lambda 生活
コンテナで始める柔軟な AWS Lambda 生活コンテナで始める柔軟な AWS Lambda 生活
コンテナで始める柔軟な AWS Lambda 生活
 
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
 
Fargate起動歴1日の男が語る運用の勘どころ
Fargate起動歴1日の男が語る運用の勘どころFargate起動歴1日の男が語る運用の勘どころ
Fargate起動歴1日の男が語る運用の勘どころ
 
Photon Fusionのはじめの一歩
Photon Fusionのはじめの一歩Photon Fusionのはじめの一歩
Photon Fusionのはじめの一歩
 
決済サービスの監視を支えるElastic Stack
決済サービスの監視を支えるElastic Stack決済サービスの監視を支えるElastic Stack
決済サービスの監視を支えるElastic Stack
 
CircleCI vs. CodePipeline
CircleCI vs. CodePipelineCircleCI vs. CodePipeline
CircleCI vs. CodePipeline
 
Azure Blob Storageへの様々なアクセス方法を比べてみた JAZUG12周年イベント
Azure Blob Storageへの様々なアクセス方法を比べてみた JAZUG12周年イベントAzure Blob Storageへの様々なアクセス方法を比べてみた JAZUG12周年イベント
Azure Blob Storageへの様々なアクセス方法を比べてみた JAZUG12周年イベント
 
アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~
 
KeycloakでAPI認可に入門する
KeycloakでAPI認可に入門するKeycloakでAPI認可に入門する
KeycloakでAPI認可に入門する
 
なぜOpenID Connectが必要となったのか、その歴史的背景
なぜOpenID Connectが必要となったのか、その歴史的背景なぜOpenID Connectが必要となったのか、その歴史的背景
なぜOpenID Connectが必要となったのか、その歴史的背景
 
JJUG CCC リクルートの Java に対する取り組み
JJUG CCC リクルートの Java に対する取り組みJJUG CCC リクルートの Java に対する取り組み
JJUG CCC リクルートの Java に対する取り組み
 
FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術
 
[Container Runtime Meetup] runc & User Namespaces
[Container Runtime Meetup] runc & User Namespaces[Container Runtime Meetup] runc & User Namespaces
[Container Runtime Meetup] runc & User Namespaces
 
Azure Media Services 大全
Azure Media Services 大全Azure Media Services 大全
Azure Media Services 大全
 
Spring Boot + Netflix Eureka
Spring Boot + Netflix EurekaSpring Boot + Netflix Eureka
Spring Boot + Netflix Eureka
 
AWS Black Belt Online Seminar 2016 Amazon EC2 Container Service
AWS Black Belt Online Seminar 2016 Amazon EC2 Container ServiceAWS Black Belt Online Seminar 2016 Amazon EC2 Container Service
AWS Black Belt Online Seminar 2016 Amazon EC2 Container Service
 
[Cloud OnAir] クラウドからエッジまで!進化する GCP の IoT サービス 2018年11月22日 放送
[Cloud OnAir]  クラウドからエッジまで!進化する GCP の IoT サービス 2018年11月22日 放送[Cloud OnAir]  クラウドからエッジまで!進化する GCP の IoT サービス 2018年11月22日 放送
[Cloud OnAir] クラウドからエッジまで!進化する GCP の IoT サービス 2018年11月22日 放送
 
Railsで作るBFFの功罪
Railsで作るBFFの功罪Railsで作るBFFの功罪
Railsで作るBFFの功罪
 
WebブラウザでC#実行 WebAssemblyの技術
WebブラウザでC#実行 WebAssemblyの技術WebブラウザでC#実行 WebAssemblyの技術
WebブラウザでC#実行 WebAssemblyの技術
 

Similar to Realmの暗号化とAndroid System

Android Studioの魅力
Android Studioの魅力Android Studioの魅力
Android Studioの魅力Keiji Ariyama
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/AndroidセキュアコーディングMasaki Kubo
 
Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Daisuke Hiraoka
 
SEAndroid -AndroidのアーキテクチャとSE化について-
SEAndroid -AndroidのアーキテクチャとSE化について-SEAndroid -AndroidのアーキテクチャとSE化について-
SEAndroid -AndroidのアーキテクチャとSE化について-Hiromu Yakura
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platformToru Yamaguchi
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発papamitra
 
Google I/O 2013 報告会 Android Studio と Gradle
Google I/O 2013 報告会 Android Studio と GradleGoogle I/O 2013 報告会 Android Studio と Gradle
Google I/O 2013 報告会 Android Studio と GradleKeishin Yokomaku
 
初めてのPadrino
初めてのPadrino初めてのPadrino
初めてのPadrinoTakeshi Yabe
 
Play2 scalaを2年やって学んだこと
Play2 scalaを2年やって学んだことPlay2 scalaを2年やって学んだこと
Play2 scalaを2年やって学んだことdcubeio
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介Shinya Okano
 
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
.NET最先端技術によるハイパフォーマンスウェブアプリケーション.NET最先端技術によるハイパフォーマンスウェブアプリケーション
.NET最先端技術によるハイパフォーマンスウェブアプリケーションYoshifumi Kawai
 
初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣Yuji Takayama
 
Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.Yuki Higuchi
 
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
Next2Dで始めるゲーム開発  - Game Development Starting with Next2DNext2Dで始めるゲーム開発  - Game Development Starting with Next2D
Next2Dで始めるゲーム開発 - Game Development Starting with Next2DToshiyuki Ienaga
 
復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0Yuta Matsumura
 
laravel x モバイルアプリ
laravel x モバイルアプリlaravel x モバイルアプリ
laravel x モバイルアプリMasaki Oshikawa
 
冬だからAndroid再入門
冬だからAndroid再入門冬だからAndroid再入門
冬だからAndroid再入門Katsumi Honda
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回Naoyuki Yamada
 

Similar to Realmの暗号化とAndroid System (20)

Android Studioの魅力
Android Studioの魅力Android Studioの魅力
Android Studioの魅力
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/Androidセキュアコーディング
 
Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!
 
SEAndroid -AndroidのアーキテクチャとSE化について-
SEAndroid -AndroidのアーキテクチャとSE化について-SEAndroid -AndroidのアーキテクチャとSE化について-
SEAndroid -AndroidのアーキテクチャとSE化について-
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
 
Google I/O 2013 報告会 Android Studio と Gradle
Google I/O 2013 報告会 Android Studio と GradleGoogle I/O 2013 報告会 Android Studio と Gradle
Google I/O 2013 報告会 Android Studio と Gradle
 
初めてのPadrino
初めてのPadrino初めてのPadrino
初めてのPadrino
 
Play2 scalaを2年やって学んだこと
Play2 scalaを2年やって学んだことPlay2 scalaを2年やって学んだこと
Play2 scalaを2年やって学んだこと
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
.NET最先端技術によるハイパフォーマンスウェブアプリケーション.NET最先端技術によるハイパフォーマンスウェブアプリケーション
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
 
ScalaMatsuri 2016
ScalaMatsuri 2016ScalaMatsuri 2016
ScalaMatsuri 2016
 
AndroidでDIxAOP
AndroidでDIxAOPAndroidでDIxAOP
AndroidでDIxAOP
 
初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣
 
Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.
 
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
Next2Dで始めるゲーム開発  - Game Development Starting with Next2DNext2Dで始めるゲーム開発  - Game Development Starting with Next2D
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
 
復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0
 
laravel x モバイルアプリ
laravel x モバイルアプリlaravel x モバイルアプリ
laravel x モバイルアプリ
 
冬だからAndroid再入門
冬だからAndroid再入門冬だからAndroid再入門
冬だからAndroid再入門
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
 

More from Keiji Ariyama

Vuzix Developer Conference
Vuzix Developer ConferenceVuzix Developer Conference
Vuzix Developer ConferenceKeiji Ariyama
 
Android Studio開発講座
Android Studio開発講座Android Studio開発講座
Android Studio開発講座Keiji Ariyama
 
2015年のAndroidアプリ開発入門 - ABCD 2015 Kanazawa
2015年のAndroidアプリ開発入門 - ABCD 2015 Kanazawa2015年のAndroidアプリ開発入門 - ABCD 2015 Kanazawa
2015年のAndroidアプリ開発入門 - ABCD 2015 KanazawaKeiji Ariyama
 
Vuzix developer conference - M100アプリ開発
Vuzix developer conference - M100アプリ開発Vuzix developer conference - M100アプリ開発
Vuzix developer conference - M100アプリ開発Keiji Ariyama
 
Google Glassアプリ開発と自由度の変遷
Google Glassアプリ開発と自由度の変遷Google Glassアプリ開発と自由度の変遷
Google Glassアプリ開発と自由度の変遷Keiji Ariyama
 
Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築Keiji Ariyama
 
Google Mirror API勉強会 20130607
Google Mirror API勉強会 20130607Google Mirror API勉強会 20130607
Google Mirror API勉強会 20130607Keiji Ariyama
 
これからの"日付変更線"の話をしよう
これからの"日付変更線"の話をしようこれからの"日付変更線"の話をしよう
これからの"日付変更線"の話をしようKeiji Ariyama
 
20130119 adkハンズオン発表資料
20130119 adkハンズオン発表資料20130119 adkハンズオン発表資料
20130119 adkハンズオン発表資料Keiji Ariyama
 

More from Keiji Ariyama (9)

Vuzix Developer Conference
Vuzix Developer ConferenceVuzix Developer Conference
Vuzix Developer Conference
 
Android Studio開発講座
Android Studio開発講座Android Studio開発講座
Android Studio開発講座
 
2015年のAndroidアプリ開発入門 - ABCD 2015 Kanazawa
2015年のAndroidアプリ開発入門 - ABCD 2015 Kanazawa2015年のAndroidアプリ開発入門 - ABCD 2015 Kanazawa
2015年のAndroidアプリ開発入門 - ABCD 2015 Kanazawa
 
Vuzix developer conference - M100アプリ開発
Vuzix developer conference - M100アプリ開発Vuzix developer conference - M100アプリ開発
Vuzix developer conference - M100アプリ開発
 
Google Glassアプリ開発と自由度の変遷
Google Glassアプリ開発と自由度の変遷Google Glassアプリ開発と自由度の変遷
Google Glassアプリ開発と自由度の変遷
 
Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築
 
Google Mirror API勉強会 20130607
Google Mirror API勉強会 20130607Google Mirror API勉強会 20130607
Google Mirror API勉強会 20130607
 
これからの"日付変更線"の話をしよう
これからの"日付変更線"の話をしようこれからの"日付変更線"の話をしよう
これからの"日付変更線"の話をしよう
 
20130119 adkハンズオン発表資料
20130119 adkハンズオン発表資料20130119 adkハンズオン発表資料
20130119 adkハンズオン発表資料
 

Realmの暗号化とAndroid System