September 27, 2008

PHP 的 OpenSSL 库 12:23 pm

书接上回,在研究 XML 签名之前先研究一下 OpenSSL 库。

签名和原理

PHP 签名的函数原型是:

bool openssl_sign ( string $data , string &$signature , mixed $priv_key_id [, int $signature_alg ] )

大四时学的密码学全忘光了,用 Google CodeSearch 搜了一气 OpenSSL 的源代码才搞明白了签名的原理。

生成签名:

  1. 对 $data 按照 $signature_alg 设置的算法(默认是OPENSSL_ALGO_SHA1)进行 hash 运算
  2. 用私钥加密($priv_key_id)
  3. $signature 就是产生的签名数据,连同 $data 发送给接收方

可用的 hash 算法包括:

  • OPENSSL_ALGO_SHA1
  • OPENSSL_ALGO_MD5
  • OPENSSL_ALGO_MD4
  • OPENSSL_ALGO_MD2

验证:

  1. 用公钥解密签名数据
  2. 解密后的结果是 $data 的 hash 值,接受方再生成 $data 的 hash 值与之对比

签名验证算法

最常见的有两种:基于大数因子分解问题的数字签名(RSA),基于离散对数问题的数字签名(DSA),公私钥分别对应 ~/.ssh/id_rsa & ~/.ssh/id_rsa.pub 和 ~/.ssh/id_dsa & ~/.ssh/id_dsa.pub
二者区别在于 RSA 还可以用于加密,而 DSA 只能用于签名验证,二者签名效率相近,但 RSA 的验证要远快于 DSA。

所以 PHP 中使用 RSA,公私钥可以用 OpenSSL 工具包生成:

openssl genrsa 512 >id_rsa
openssl rsa -pubout id_rsa.pub

我在 .ssh 目录下的 RSA 公私钥是用 ssh-keygen 生成的,但在在这里做试验失败,可能于密钥长度有关系。

验证函数原型:

int openssl_verify  (  string $data  ,  string $signature  ,  mixed $pub_key_id  [,  int $signature_alg = OPENSSL_ALGO_SHA1  ] )

很好理解,$data 是接受方获取的数据,$signature 是一起发过来的签名,$pub_key_id 是校验用的公钥,$signature_alg 就是前面制定的 hash 算法了。

加密

函数原型:

int openssl_seal  ( string $data  , string &$sealed_data  , array &$env_keys  , array $pub_key_ids  )
  1. 用随机字符串加密 data ( RC4 加密算法)
  2. 用 pub_key_ids 里的公钥对共享密钥进行加密,将结果保存在 env_keys
  3. 将 env_keys 和 sealed_data 发送给接收方

解密

函数原型:

bool openssl_open  ( string $sealed_data  , string &$open_data  , string $env_key  , mixed $priv_key_id  )
  1. 私钥揭开 env_key
  2. 用 env_key 打开加密消息

用 PHP 创建公私钥

function get_key_pair() {
    $ret = array();
    $res = openssl_pkey_new();
    openssl_pkey_export($res, $ret['private_key']);
    $pub_key = openssl_pkey_get_details($res);
    $ret['public_key'] = $pub_key['key'];
    return $ret;
}
Filed under: Programming — Tags: Comments (0)

September 25, 2008

在 PHP 中使用 XMLRPC 10:22 pm

这几天在研究 Moodle Network 组件,通过这个模块,各个孤立的系统被连接到了一起,实现了单点登录和资源共享(对于 e-learning 有很大的意义),通信协议是 XML-RPC,信息安全不是依赖 SSL 的方案,而是在采用了 XML 签名(不对称加密算法),想法非常好,但实现的不太完整,因为这个模块的原作者离开了在新西兰的公司,整得像个半完成作品。

今天看了一下代码,打算在这上面解决多 Moodle 系统的资源共享问题(包含点对点和 HUB 模式),之前没用过 XMLRPC,所以现在开始学一下,我用的是 PHP 的 XMLRPC 模块(比纯 PHP 实现快了不少)。

首先实现一个 XMLRPC 服务,我封装了一个简单的类:

class xmlrpc_server {
    private $server;
    public function __construct() {
        $this->server = xmlrpc_server_create();
    }
    public function add($name, $func) {
        xmlrpc_server_register_method($this->server, $name, $func);
    }
    public function run() {
        $req = file_get_contents('php://input');
        $response = xmlrpc_server_call_method($this->server, $req, null);
        echo $response;
        xmlrpc_server_destroy($this->server);
    }
}

调用这个类创建一个服务:

header('Content-Type: text/xml');
function func_add($method, $params) {
    return $params[0]+$params[1];
}
$xmlrpc = new xmlrpc_server;
$xmlrpc->add('add', 'func_add');
$xmlrpc->run();

PHP 客户端的调用是通过 HTTP 的 POST 方法,我用的是 cURL 扩展:

require_once('curl.class.php');
class xmlrpc_client {
    public function __construct($url, $autoload = false) {
        $this->connection = null;
        $this->url = $url;
        $this->connection = new curl;
        $this->methods = array();
        if ($autoload) {
            $resp = $this->call('system.listMethods', null);
            $this->methods = $resp;
        }
    }
    public function call($method, $params = null) {
        $post = xmlrpc_encode_request($method, $params);
        return xmlrpc_decode($this->connection->post($this->url, $post));
    }
}
header('Content-Type: text/plain');
$rpc = "http://10.0.0.10/api.php";
$client = new xmlrpc_client($rpc, true);
print_r($client->call('add', array(199,2)));

待续,下一步优化代码并实现 XML 签名技术。

资料:

XML Signature Syntax and Processing
OpenSSH
XML Encryption Syntax and Processing

== TO BE CONTINUED ==

Filed under: Programming — Tags: , Comments (1)

September 24, 2008

Gentoo 上的 Python 没有 sqlite 支持 9:20 pm

Sqlite 从 Python 2.5 以后就是标准模块了,但 Gentoo 上的 Python 竟然没有这个模块,开始以为需要一个额外的包,但安装 pysqlite 以后问题依旧(过后才想起来是没进入标准前的一个模块),于是使用 USE 标签重新编译 Python:

USE="sqlite" emerge python

问题解决

Filed under: Programming,System — Tags: , , Comments (0)