yanbin's Blog

为 Android 程序创建 CA keystore 以及 self-signed keystore 的方法

为什么 Android 程序需要 CA KeyStore?
1. 在 Android 程序中建立一条 SSL/TLS 连接时,受信任 CA (Trusted CAs) 用来验证 server。
    Public-Key Infrastructure (PKI) 中有 trust certs 概念,许多网络工具实现了 trusted CA 的使用。
    比如: curl, Android URLConnection.
    Android 系统中有一个 trusted CAs list, 包含 100 多个 trusted CAs.
  
2. 建立 SSL/TLS 连接时现有的 trusted CAs 不能验证服务器证书,会引发一个 security exception:
       javax.net.ssl.SSLHandshakeException: ... : Trust anchor for certification path not found.
   具体而言,以下这些情况会引发这个问题:
      (a) The CA that issued the server certificate was unknown;
      (b) The server certificate wasn't signed by a CA, but was self signed;
      (c) The server configuration is missing an intermediate CA;
 
3. 针对(a) 和 (b) 这两种情况,解决方法是创建 SSL/TLS 连接时使用 Android TurstManager 工具。
    在 Android 程序中 TrustManager 用 KeyStore instance 初始化,而 KeyStore instance 读取/解析
    BKS/JKS 格式的 KeyStore 文件,获得证书信息。
 

继续阅读

自签发 SSL/TLS 证书的方法以及遇到的一些问题

PKI (Public Key Infrastructure, 公开密钥基础架构)简介
0. 目的
PKI 旨在创造、管理、分配、使用、存储以及撤销数字证书
Unix/Linux 平台上常用的 PKI 软件是 openssl.
 
1. 数字证书是什么?
在密码学上视数字证书为一种身份凭证,是一种电子文件,用于证明公开密钥的所有者的身份。
数字证书文件中包含所有者的身份信息、公开密钥信息以及数字证书本身的数字签章;
数字签章用于验证证书文件内容正确无误——没有损坏或者没有被修改过——。
如果签章是正确的,而用户可以相信签署者,之后用户就知道他们可以使用这个密钥,来与密钥的拥有者进行通信。在X.509中规范了这个认证的过程与标准。①
认证过程中会包含「用 CA 的根(roo)证书验证这份数字证书是由该 CA 签发的」。
用户可以没有自己的数字证书,但是一定需要 CA 的根证书。比如:https 通信。
 
2. 谁负责创造数字证书?
CA(Certificate Authority) 负责签发数字证书。
CA 由受信任第三方担任,签发数字证书给通信双方使用;有时只签发给服务方,比如: https 通信。
这样理解或许比较简单,互联网上的数字证书签发实际上要复杂。
我们自己签发证书给自己的程序使用,不公开业务也不公开 CA root 证书,可以不用关心太多。
 
大公司的内部业务也可能足够复杂的到需要 CA,RA 之类的。参见维基百科公开密钥基础建设
 
也有 12306 或者银行这样的公司要求用户自己下载它的 CA 的 root 证书。
 
3. 证书的层级结构。
 
设置 CA 信息和签发 CA root 证书
0.修改 openssl.conf 文件里的某些域的值。
req_distingushed_name section 可以考虑修改为:
[ req_distinguished_name ]
   countryName = Country Name (2 letter code)
   countryName_default = CN
   stateOrProvinceName = State or Province Name (full name)
   stateOrProvinceName_default = ShangHai

   localityName = Locality Name (eg, city)
   localityName_default = ShangHai
   0.organizationName = Organization Name (eg, company)
   0.organizationName_default = My Company Name

   organizationalUnitName = Organizational Unit Name (eg, section)
   organizationalUnitName_default = May Project

1. 生成 CA root key (根密钥); CA root key 非常重要。
a) 不仅签发或更新 CA root 证书需要。
b) 签发通信双方数字证书时也需要。

Create the keypair:
$ openssl genrsa -des3 -out root-ca.key 1024
 

0) 指定了 -des3 选项,openssl 要求输入 pass phrase;
pass phraseroot key 的密码;
CA 签发数字证书时需要输入这个密码,算是一种防范措施吧。

1) FIXME: 这种密码也可以用到普通证书的 key,
程序使用证书和 key 时, 一般会要求输入密码,可以作为用户密码用吗?

2) FIXME: 1024 是 key  的长度目前也支持 2048, 这两个值有很大的区别吗?

key 的长度为 2048 会耗费更多的 CPU 资源吧。

2. 自签发 CA 根证书(root certificat)
Use the key to sign itself:
$ openssl req -new -x509 -days 3650 -key root-ca.key -out root-ca.crt  -config openssl.cnf
0) 关键参数是 -x509:
生成的 root-ca.crt 是一个 self-signed X.509 certificate;

1) 这条命令将两个步骤合二为一。
a) 使用 private key 生成 certificate request; 需要填写证书持有者的信息;
b) 使用 certificate request 签发证书(singed)或自签发证书(self-signed);

2) 这个自签发证书为什么能做为 CA root certificate 使用?
因为指定了参数 -x509, openssl 配置文件 req section 指定了 x509_extensions = v3_ca;
而 v3_ca section 里则有:basicConstraints = CA:true
 
3) openssl.cnf 以及 CA directory 都不是系统中唯一存在的;
任意创建一个目录,创建配置文件(比如: openssl.cnf),也可以签发根证书。
$ mkdir demoCA && cd demoCA
$ touch index.txt
$ echo 01 > serial
$ mkdir private #指定 private_key=/path/to/demoCA/myCA/private/root-ca.key
$ mkdir myCA # 指定 CA_default:dir=/path/to/demoCA/myCA
 
4) 可以使用如下命令查看 root-ca.crt 的信息
$ openssl x509 -noout -text -in root-ca.crt

继续阅读

使用 libmosquitto 遇到的几个问题

1. 使用 libmosquitto 时必须要调用 mosquitto_loop_forever() 或者 mosquitto_loop();
 
2. mosquitto_loop_forever(); mosquitto_loop() 的第三个参数 max_packets 目前并没有使用,
    但是为了保持兼容性,必须设置为 1.
 
3. mosquitto_loop_start() 并不是在 thread 中调用,而是会启动一个 thread 处理 network  traffic, 
    称为 network thread; 同样的 mosquitto_loop_stop() 不是一定要在 thread 中调用,
    而是结束之前通过 mosquitto_loop_start() 创建的 network thread,
    mosquitto_loop_stop() 会等待 network thread 结束,而为了让 network thread 结束,
    又必须提前调用 mosquitto_disconnect(),
    不过可以通过设置 mosquitto_loop_stop() 的第二参数来强制 network thread 结束;

 
4.  注册 will message 同时指定 will topic。mosquitto_will_set() 的第二个参数就是指定 will topic 的。
     这就是 mqtt 里所说的 will message 有相应的 topic,  mosquitto_sub, mosquitto_pub 都有参数,
     可以指定 will topic: --will-topic;
 
5. 如果不使用 mosquitto_loop() 或者 mosquitto_loop_forever() 可以使用:
    (a) mosquitto_socket() 获取 connect socket handle;
    (b) 使用 select() 查询 socket handle 可读/可写;

继续阅读

mqtt 基础

0. mqtt 是一种轻量级的 publish/subscribe 消息传输协议。
   这是一个应用层协议, 一种互联网通信协议,并不依赖底层网络协议。
   正因为其轻量级,所以在低电量设备的中广泛应用。mqtt 可以应用在更多的情景。
   常见的应用:facebook, 微博。
 
1. mqtt message 规格:
   MAX LENGTH: The Payload length valid values are between 0 and 268,435,455 (0xf,fff,fff).
   没错是 7 个f, 256 * 1024 * 1024 - 1.
 
2. mqtt 之 "pub/sub":
   mqtt 的基础原理是推送消息(publishing messages)和订阅主题(subscribing topics), 称为 "pub/sub".
   clients 连接到 broker ---> subscrib topics, 其他 clients 连接到 broker ---> publish message 到 topic,
   所有订阅了这个 topic 并且在线的 clients 都会收到这条 message.
 
   假如 clients publish message 到 topic, 但是订阅这个 topic 的 clients
   都没有在线, 或者还没有 client 订阅这个 topic. 这条 message 将会被消失(被丢弃了?是的被丢弃了)。
   可以设置 message 的 retained flag,再有其他 client 订阅到 topic 时会收到这条 message.
 
   1) 如果 publish message 时有 client 订阅到 topic, 这个条 message 还会保留吗?
   2) FIXME: 保留的 message 发送过之后还会再次发送到其他后来订阅到 topic 的 client 吗?
      **** retained message 保证每当 client 订阅 topic 时,会把 message 发送到 client.
            所有新在线的 client 都可以收到这条 message 直到 borker 进程重启。
      **** 即使 broker 进程重启,也有办法从硬盘存储中读取之前的消息,并且按照消息类型安排发送。
 
3. mqtt, broker:
   提供通用的简单的接口,接受其他 client 的连接。client 可以将 subscribedmessage 存入 database、
   发送到 twitter. 当然也可以从 database, twitter 读取 message 并推送。
   协议接口是简单通用的,任何实现的 client 都可以连接到任何实现的 broker.
 

继续阅读




Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee