安全分析

编者:厦门大学信息学院通信工程系2015级研究生:杨江河,阮晓杨,赖雅玲

源码目录位置:bdk/system/security/

1.概述


在Android中/system/ keystore进程提供了一个安全存储的服务。每一个Android用户都有一块其私有的安全存储区域。keystore是java的密钥库,用来进行通信加密,比如数字签名。同时keystore用来保存密钥对,比如公钥和私钥。所有秘钥信息使用一个随机key并用AES加密算法加密,加密好的密文采用另外一个key加密后保存到本地磁盘。在近期的一些Android版本中,证书管理(例如RSA算法的私有key)是可以通过专门的硬件做支持的。这也就是说,keystore的key只是用来标识存储在专有硬件上的真正key。Fig.1很好的阐述了keystore安全存储机制的工作原理。

        Fig.1 The keystore service

2.Security目录重要文件框架


+--Keystore  
|  +--include  
|  +--test  
|   --keystore_main.cpp  
|   --keystore_cli_v2.cpp  
+--keystore-engine  
|   --android_engine.cpp  
|   --keyhandle.cpp
+--softkeymaster  
|  +--include
|  |  --keymaster
|      --softkeymaster
|   --Android.mk
|   --keymaster_openssl.cpp
|   --module
--MODULE_LICENSE_APACHE2
--NOTICE

3.keystore主函数解释说明


*keystore_main.cpp

KeyStore是密钥对的安全容器。在这个工具中,每个文件储存在一个密钥对中。密钥被编码到文件中,键值用校验和加密。加密的键值被用户定义的密码保护。为了让事情变得简单,缓存总是大于所需的最大空间,所以缓存的边界检查总是被省略。

keymaster2_device_t* dev; if (keymaster_device_initialize(&dev)) { ALOGE("keystore keymaster could not be initialized; exiting"); return 1; }

密钥设备初始化

keymaster2_device_t* fallback; if (fallback_keymaster_device_initialize(&fallback)) { ALOGE("software keymaster could not be initialized; exiting"); return 1; }

回调密钥设备初始化程序

android::IPCThreadState::self()->joinThreadPool();

因为只存在一个进程,所以我们只能把处理绑定事物处理当成一个单线程程序

keymaster_device_release(dev);

删除密钥设备

KeyStore主要文件功能描述

文件名 功能描述
auth_token_table.cpp 基于标准算法的遍历模板封装以及授权的相关操作
blob.cpp 二进制大文件的读写和,大小控制和加密控制
entropy.cpp 加密算法的开启和随机数据的生成
IKeystoreService.cpp Parcel数据的读写,Token接口数据的增加,删除,更新和列出
key_store_service.cpp 密钥服务的增加,删除,更新显示;密钥服务的状态获取和重启
keyblob_utils.cpp 获取软键头尺寸并添加软键头
keystore.cpp 密钥库的构造和析构,密钥库的初始化以及管理键的复制和读写
keystore_cli_v2.cpp 文件的读写和密钥的产生、删除和导出
keystore_client_impl.cpp 主要是密钥库客户端实现的操作,包括生成随机数加密,导入、导出、生成、删除和列出密钥,加密算法采用AES-256-CBC,并且授权算法是HMAC-SHA256
keystore_get.cpp 密钥库的获取
keystore_utils.cpp 文件的读写,添加密钥授权以及APP和用户ID的获取
operation.cpp 操作图的添加,获取,更新和移除
permissions.cpp SELinux系统的配置,SELinux系统下密钥库的权限检查以及密钥库euid的获取
user_state.cpp 用户状态的初始化、设置和重启;键值文件的复制以及从密码中生成密钥

4.Makefile文件分析


keystore-engine/Android.mk

LOCAL_PATH := $(call my-dir)

提示当前文件的路径,必须定义在文件开头 my-dir 返回当前Android.mk所在的目录路径。

include $(CLEAR_VARS)

CLEAR_VARS 变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx.
例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH.
这个清理动作是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能避免相互影响。

ifneq (,$(wildcard $(TOP)/external/boringssl/flavor.mk))
    include $(TOP)/external/boringssl/flavor.mk
else
    include $(TOP)/external/openssl/flavor.mk
endif

如果boringssl/flavor.mk文件存在,则先读取/boringssl中的flavor.mk。
否则读取/openssl下的flavor.mk文件。

LOCAL_MODULE := libkeystore-engine

指定当前模块的名字为libkeystore-engine,这个模块名字是唯一的且不能被更改。
Build System会自动添加适当的前缀和后缀。例如:foo;要产生动态库则生成libfoo.so。 但请注意!如果模块名被定为:libfoo.则生成libfoo.so不再加前缀。

  LOCAL_SRC_FILES := \
    android_engine.cpp

指定当前模块所包含的文件为android_engine.cpp。 不必列出头文件,build System会自动帮我们找出依赖文件

LOCAL_C_INCLUDES+= \
    external/openssl/include \
    external/openssl

设置头文件的搜索路径,默认的头文件的搜索路径是LOCAL_PATH目录。

LOCAL_SHARED_LIBRARIES += \
    libcrypto \
    liblog \
    libcutils \
    libutils \
    libbinder \
    libkeystore_binder

表示模块在运行时要依赖的共享库(动态库),在链接时就需要,以便在生成文件时嵌入其相应的信息。
注意:它不会附加列出的模块到编译图,也就是仍然需要在Application.mk中把它们添加到程序要求的模块中。

LOCAL_MODULE_TAGS := optional

指定模块编译运行的版本,一共有四个选项:
user: 指该模块只在user版本下才编译
eng: 指该模块只在eng版本下才编译
tests: 指该模块只在tests版本下才编译
optional:指该模块在所有版本下都编译

LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk

增加额外的依赖 如果模块需要依靠一些并不直接建立的文件,就可以将这些编译标签加入到LOCAL_MODULE_TAGS里面去,通常这个是一些无法自动创建的附属工程文件。

include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY:是Build System提供的一个变量,指向一个GNU Makefile Script。
它负责收集自从上次调用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定编译为什么。


softkeymaster/Android.mk

ifeq ($(USE_32_BIT_KEYSTORE), true)
LOCAL_MULTILIB := 32
endif

设置如果使用的是32位的静态库的时候,要将LOCAL_MULTILIB的值设置为32。

LOCAL_CFLAGS = -fvisibility=hidden -Wall -Werror

一个可选的设置,在编译C/C++ source 时添加如Flags。
用来附加编译选项。 注意:不要尝试在此处修改编译的优化选项和Debug等级。它会通过您Application.mk中的信息自动指定。
也可以指定include 目录通过:LOCAL_CFLAGS += -I。 这个方法比使用LOCAL_C_INCLUDES要好。因为这样也可以被ndk-debug使用。


keystore/Android.mk

LOCAL_MODULE_CLASS := SHARED_LIBRARIES

LOCAL_MODULE_CLASS 标识了所编译模块最后放置的位置,如果不指定,不会放到系统中,之后放在最后的obj目录下的对应目录中。

代码 注释
LOCAL_MODULE_CLASS := ETC #表示放于system/etc目录
LOCAL_MODULE_CLASS := EXECUTABLES #放于/system/bin
LOCAL_MODULE_CLASS := SHARED_LIBRARIES #放在/system/lib下

5. 参考链接

results matching ""

    No results matching ""