AndroidPi

HTTPS与SSL/TLS协议

HTTPS(Hypertext Transfer Protocol Secure)译为超文本传输安全协议,也称为HTTP over TLS,HTTP over SSL或HTTP Secure,它对HTTP协议进行的扩展,用于在计算机网络上进行安全通信。其主要目的是对站点服务器进行身份认证,保护交换数据的隐私与完整性。 SSL/TLS协议 HTTP协议位于TCP/IP四层模型最高层的应用层。HTTPS是在HTTP所在的应用层加入一个子层,位于HTTP子层之下,传输层之上。 根据RFC: TLS协议的主要目的是为两个通信应用间提供隐私与数据完整性。该协议主要由两层组成:TLS Record协议和TLS Handshake协议。在某个稳定的传输协议(如TCP)之上,在最底层是TLS Record协议。 TLS Record协议所提供的连接安全性有两个基本属性: 连接是私有的。 对称加密用于数据加密(例如AES, RC4等),每个连接都会生成唯一的对称加密秘钥,并且该秘钥是基于另一个协议(例如TLS Handshake协议)经过协商后的秘钥得来的。Record协议也可以不使用加密。 连接是可靠的。 消息传输包含一个使用一个使用秘钥的MAC的消息完整性检查。安全哈希函数(例如,SHA-1等)用于MAC计算。Record协议可以不使用MAC进行运行,但这种情况通常仅使用在这种模式下,即另一个协议将Record协议作为协商安全参数的传输器。 TLS Record协议用于封装更高层级的协议。其中一个就是TLS Handshake协议,它允许服务器和客户端对彼此进行认证并且在应用层协议传输和接收数据的第一个字节前协商一个加密算法以及要使用的秘钥。 TLS Handshake协议提供的连接安全性有三个基本性质: 对等端的身份可以使用非对称加密或公钥密码学(如,RSA,DSA等)进行认证,这种认证是可选的,但一般需要对等端至少一方进行认证。 对共享秘钥的协商是安全的:协商的秘钥是不能被窃听者获取的,并且对任意未认证的连接都不能获取到秘钥,即使攻击者位于连接的中间。 协商是可靠的:没有攻击者能够修改协商通信内容并且不被通信方发现。 TLS的一项优点是它是与应用协议独立的,更高层级的协议可以透明地置于TLS协议之上。TLS标准并没有指定什么协议可以使用TLS来添加安全性,如何初始化TLS握手以及如何解释认证证书交换的决定留给TLS之上的协议的设计者和实现者。 HTTPS连接的建立与加密通信 在实现中,SSL/TLS子层作为HTTP子层和传输层的中间层,对套接字接口进行了一层封装,用于建立安全连接与通信。会话状态的加密参数是通过TLS握手协议来生成的,当一个TLS客户端和服务端首次开始进行通信时,它们在一个协议版本上达成一致、选择密码学算法、可选地对对方进行认证,并使用公钥加密技术来生成共享秘钥。 它包含如下步骤: 交换hello消息来对算法达成一致,交换随机值并进行恢复会话的检查 交换必要的机密参数,运行客户端和服务端对预主密钥(premaster secret)达成一致 交换证书和密码学信息,允许客户端和服务端对彼此进行认证 从预主密钥(premaster secret)生成一个主密钥并交换随机值 为Record层提供安全参数 允许客户端和服务端确认它们的对等端计算出相同的安全参数并且握手没有被攻击者干预 TLS握手的完整步骤如下所示(其中带*表示可选的或根据情况进行发送的消息,并不总是会发送): Client Server ClientHello --------> ServerHello Certificate* ServerKeyExchange* CertificateRequest* <-------- ServerHelloDone Certificate* ClientKeyExchange CertificateVerify* [ChangeCipherSpec] Finished --------> [ChangeCipherSpec] <-------- Finished Application Data <-------> Application Data 可以使用openssl提供的工具来查看这一步骤的实际数据交换情况:...

August 10, 2018 · 26 min · 5368 words · LEOY

CA与SSL/TLS证书

CA 证书颁发机构(CA, Certificate Authorities)根据认证操作规则 (CPS) 授权颁发、暂停、更新或取消证书的实体。在其颁发的所有证书和 CRL 中都可通过识别名称来识别 CA。证书颁发机构必须公布其公钥,或者如果该证书颁发机构隶属一级证书颁发机构,则由更高级的 CA 提供证书证明其公钥的合法性。 数字证书(Digital Certificates)是可进行验证的包含身份证明的小的数据文件,它可以帮助网站、个人、设备来代表他们真实可信的在线身份(可信是因为CA已经对身份进行了验证)。CA在互联网上的操作以及如何进行透明可信的事务中扮演了关键角色。每年,证书机构都会颁发上百万的数字证书,它们用于保护信息,加密数以十亿计的事务,并确保安全的通信。 如何保证CA可信 浏览器、操作系统和移动设备会运行一个已授权的CA成员资格程序,其中一个CA必须满足详细的标准才能够被接受作为其中一员。一旦所接受的CA能够颁发直接被浏览器信任的证书,随后,人们和设备就可以依赖该证书进行工作。仅有少量经过授权的CA,从私有公司到政府机构都有,并且CA运作的越久,就会有越多的浏览器和设备信任该CA颁发的证书。 在颁发一个数字证书前,CA会对申请者的身份进行一些检查。这些检查与所申请的证书类型相关,例如,一个对域名所有权进行验证的SSL证书(Domain Validated (DV SSL) Certificates)会将已经验证了所有权的域名包含到证书中。而一个可扩展SSL(Extended Validation SSL)会包含公司相关的额外信息,这些信息由CA通过许多公司检查进行验证。 证书有许多种类型,不仅仅是支持SSL,还可以用于对人员和设备进行认证,对代码和文档添加合法性证明等。 PKI与信任层级 浏览器和设备通过在其根证书库(Root Store)中接受根证书(Root Certificate)来信任一个CA,这个根证书库本质上是一个预先安装在浏览器或设备上的已信任CA数据库。Windows、Apple、Mozilla以及一般的移动媒介都运行自己的根证书库。 各CA使用这些预安装的根证书来办法中介根证书和终端实体数字证书。CA接收证书请求,验证申请者,颁发证书,并对依赖于该证书的任何人发布已颁发证书的持续的有效性状态。 CA通常会创建一些中介CA(ICA,Intermediate CA),用于办法终端实体证书,如SSL证书,这称为一个信任层次。 遵循最佳安全实践,CA不应该直接从发布给媒介的根证书来颁发数字证书,而应该通过一个或多个ICA。 CA是如何运作的 作为互联网中一个可信任的锚点,CA具有重大的责任。因此,在满足可审计的需求下运行一个CA是一个复杂的任务。一个CA基础设施由大量运作元素,硬件、软件、政策框架以及实践声明、审计、安保基础设施和人员组成。总体上,这些元素称为一个可信任的PKI(Public Key Infrastructure)。 SSL与TLS SSL(Secure Socket Layers)是指安全套接字层,它是一项标准技术,用于确保互联网连接安全。 TLS(Transport Layer Security)指传输层安全,它是SSL的升级版。 历史简介 SSL和TLS都是加密协议,用于提供服务器、设备、应用在网络上的认证和数据加密。SSL是先于TLS设计出的,最初它是由网景公司于1995年首先公布的,最初的版本是SSL2.0(SSL1.0从未公开发布)。在修正若干缺陷后,1996年版本2.0迅速被SSL3.0所取代。 TLS在1999年作为基于SSL3.0的一个新版本被发布,根据RFC2246: 该协议和SSL3.0没有十分巨大的差别,但已有的差别就足以使得两者不能进行互操作。 SSL2.0和SSL3.0分别在2011和2015年已经被IETF废弃,因此现在应该使用TLS协议。 SSL和TLS采用不同的加密方式。 SSL和TLS仅仅指客端和服务器端进行的握手,握手并没有进行任何加密,它仅仅是对需要共享的秘钥和加密类型上达成一致。 SSL/TLS证书 SSL证书是数字证书的一种,它用于将一个网站服务器的所有者详情和加密秘钥进行绑定。在浏览器和持有SSL证书的服务器之间,这些秘钥用于在SSL/TLS协议中激活一个安全会话。为了让浏览器相信一个SSL证书,并在不引起安全性警告的前提下建立SSL/TLS会话,SSL证书必须包含网站的域名,并且由可信任的CA颁发,并且没有过期。 SSL证书的功能 因此SSL证书主要有两个功能: 认证与验证 SSL证书中包含有关于一个人、商业或站点的身份的特定细节的可靠性信息。其中CA颁发的扩展验证SSL证书对申请人的审查标准最为严格,因此它是最值得信赖的SSL证书。 数据加密 SSL证书也可以进行加密,也就意味着通过网络交换的敏感信息不回被第三者窃取并破译出。 其用途举例如下: 保障站点和用户浏览器通信的安全 保障企业内网内部通信的安全 保障通过网络进行的邮件通信的安全 保障通过因特网或内网进行的服务器间通信的安全 保障移动设备收发信息的安全 SSL证书的类型 目前有如下几种不同类型的证书: 自签发证书 主要用于内部使用的非CA颁发的证书。如果在外部使用,因为其不具备可信任的身份认证能力,不能用于辨别伪造的服务器。 域名验证证书 可以快速进行颁发的入门级SSL证书。对申请人的验证中唯一需要确认的是其对域名的所有权。 完全认证证书...

August 10, 2018 · 1 min · 89 words · LEOY

源码分析:理解Context

Context一般翻译为上下文,它提供了一个应用环境的全局接口,用于访问指定应用的资源和类,以及各种应用级别的操作,如启动Activities与Service、发送广播与注册广播接收器、接收Intents、获取系统服务等等。 Application的Context ActivityThread.java public static void main(String[] args) { // ... ActivityThread thread = new ActivityThread(); thread.attach(false); // ... } private void attach(boolean system) { // ... if (!system) { // ... final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } // ... } // ... } ActivityManagerService.java @Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder....

June 14, 2018 · 7 min · 1431 words · LEOY

Android View事件处理机制与分发流程

View类还包含一系列嵌套接口以及您可以更加轻松定义的回调。 这些接口称为事件侦听器,是您捕获用户与UI之间交互的票证。 尽管您通常会使用事件侦听器来侦听用户交互,但有时您确实需要扩展View类以构建自定义组件。也许,您想扩展 Button类来丰富某些内容的样式。 在这种情况下,您将能够使用该类的事件处理程序为类定义默认事件行为。 API 事件侦听器(Event Listeners) 事件侦听器是View类中包含一个回调方法的接口。 当用户与UI项目之间的交互触发已注册此视图的侦听器时,Android框架将调用这些方法。 各事件侦听器接口包含的回调方法如下: onClick() 在 View.OnClickListener 中。 当用户触摸项目(处于触摸模式下)时,或者使用导航键或轨迹球聚焦于项目,然后按适用的“Enter”键或按下轨迹球时,将调用此方法。 onLongClick() 在 View.OnLongClickListener 中。 当用户触摸并按住项目(处于触摸模式下)时,或者使用导航键或轨迹球聚焦于项目,然后按住适用的“Enter”键或按住轨迹球(持续一秒钟)时,将调用此方法。 onFocusChange() 在 View.OnFocusChangeListener 中。 当用户使用导航键或轨迹球导航到或远离项目时,将调用此方法。 onKey() 在 View.OnKeyListener 中。 当用户聚焦于项目并按下或释放设备上的硬按键时,将调用此方法。 onTouch() 在 View.OnTouchListener 中。 当用户执行可视为触摸事件的操作时,其中包括按下、释放或屏幕上的任何移动手势(在项目边界内),将调用此方法。 onCreateContextMenu() 在 View.OnCreateContextMenuListener 中。 当(因持续“长按”而)生成上下文菜单时,将调用此方法。请参见菜单开发者指南中有关上下文菜单的阐述。 这些方法是其相应接口的唯一成员。 请注意,上述示例中的 onClick() 回调没有返回值,但是其他某些事件侦听器方法必须返回布尔值。具体原因取决于事件。 对于这几个事件侦听器,必须返回布尔值的原因如下: onLongClick():此方法返回一个布尔值,表示您是否已处理完事件,以及是否应该将它继续传下去。 也就是说,返回 true 表示您已经处理事件且事件应就此停止;如果您尚未处理事件和/或事件应该继续传递给其他任何点击侦听器,则返回 false。 onKey():此方法返回一个布尔值,表示您是否已处理完事件,以及是否应该将它继续传下去。 也就是说,返回 true 表示您已经处理事件且事件应就此停止;如果您尚未处理事件和/或事件应该继续传递给其他任何按键侦听器,则返回 false。 onTouch(): 此方法返回一个布尔值,表示侦听器是否处理完此事件。重要的是,此事件可以拥有多个分先后顺序的操作。 因此,如果在收到关闭操作事件时返回 false,则表示您并未处理完此事件,而且对其后续操作也不感兴趣。 因此,您无需执行事件内的任何其他操作,如手势或最终操作事件。 事件处理程序(Event Handlers) 如果您从视图构建自定义组件,则将能够定义几种用作默认事件处理程序的回调方法。在有关自定义组件的文档中,您将了解某些用于事件处理的常见回调,其中包括: onKeyDown(int, KeyEvent):在发生新的按键事件时调用 onKeyUp(int, KeyEvent):在发生按键弹起事件时调用 onTrackballEvent(MotionEvent):在发生轨迹球运动事件时调用 onTouchEvent(MotionEvent):在发生触摸屏运动事件时调用 onFocusChanged(boolean, int, Rect):在视图获得或失去焦点时调用 还有一些其他方法值得您注意,尽管它们并非 View 类的一部分,但可能会直接影响所能采取的事件处理方式。 因此,在管理布局内更复杂的事件时,请考虑使用以下其他方法:...

March 11, 2018 · 5 min · 1047 words · LEOY

Android View绘制流程

概述 当一个Activity接收到焦点,它会请求对其布局进行绘制。Android框架会处理绘制的流程,但Activity必须提供布局层次的一个根节点。 绘制从布局的根节点开始,它需要对布局树进行测量并进行绘制。绘制通过遍历布局树对每个与失效区域(invalid region)相交的View进行绘制。依次地,每个ViewGroup请求它的每个子View进行绘制(使用draw()方法)并且每个View负责绘制它自身。因为布局树采用前序遍历,这意味着父View会在子View之前(也就是图层的下方)绘制,同时该父View的兄弟View会以它们在树中出现的顺序进行绘制。 框架不会绘制失效区域外的View对象,并且会处理好View背景的绘制,你可以通过调用invalidate()方法来强制一个View进行绘制。 布局的绘制需要经过两个过程的处理: 测量 测量过程在measure(int, int)方法中实现,它是对View树的自上而下的遍历。在递归过程中,每个View将尺寸规范沿树从上往下推,在测量过程的结尾,每个View都存储其测量结果。 布局 布局过程在layout(int, int, int, int)中实现,它也是自上而下的。在这个过程中,每个父View负责对其所有子View的位置进行定位,它需要使用测量过程中计算出的视图尺寸。 当一个View对象的measure()方法返回时,其getMeasuredWidth()和getMeasuredHeight()值必须被设定,对于该View的所有子孙View对象也是一样。一个View对象的测量的宽度和高度必须遵循父View施加的约束。这可以保证在测量过程的结尾,所有父视图都接收子视图的测量。一个父视图可能会在其子视图上多次调用measure()方法。例如,父视图可能使用未指定的尺寸规格对所有子视图进行测量,来找到子视图想要有多大,如果所有子视图不受约束的尺寸之和太大或者太小,这时候父视图会使用实际的尺寸规格再次调用measure()(也就是说,如果子视图不同意它们自己获取的空间,那么父视图会在第二次测量过程中介入并设定测量规则)。 为了初始化一个布局,可以调用requestLayout()。通常当一个View相信它当前的边界已经不适合它了,那么它会在自身上调用该方法。 测量过程采用两个类对尺寸进行沟通: ViewGroup.LayoutParams 用于View对象来告知它们的父级它们想要如何被测量和定位。基础ViewGroup.LayoutParams仅描述了View在宽度和高度上想要有多大。对于每个尺寸,它可以指定如下值: 一个确切的数字 MATCH_PARENT,表示View想和父级一样大(不包括父级的padding) WRAP_CONTENT,表示View想要刚好足够包围其内容的大小(包括padding) MeasureSpec 用于从上往下将测量需求从父级推给子级。MeasureSpec可以有如下三种模式: UNSPECIFIED:一个父视图可以用他来确定一个子View所期望的尺寸。例如,一个LinearLayout可以在其子视图上调用measure(),其中将高度设置为UNSPECIFIED并且宽度设置为EXACTLY 240来找出给定一个240像素的宽度时,子视图期望有多高。 EXACTLY:用于父视图给子视图施加一个确定的尺寸。子视图必须使用该尺寸,并且保证它所有的后代视图都是符合该尺寸限制的。 AT MOST:用于父视图给子视图施加一个最大的尺寸。子视图必须保证它以及其所有的后代都符合该尺寸的限制。 源码分析 整体流程 绘制从布局的根节点开始,它需要测量和和绘制布局树。 从ViewRootImpl的首次布局请求开始: ViewRootImpl.java final class TraversalRunnable implements Runnable { @Override public void run() { doTraversal(); } } @Override public void requestLayout() { if (!mHandlingLayoutInLayoutRequest) { checkThread(); mLayoutRequested = true; scheduleTraversals(); } } void scheduleTraversals() { if (!mTraversalScheduled) { mTraversalScheduled = true; mTraversalBarrier = mHandler....

March 11, 2018 · 39 min · 8259 words · LEOY