RSA 公钥格式转换之PHP实现


在.net中公钥的格式总是以modules 、exponent的格式存在的,但是openssl做加密、解密总是使用pem格式的,这里实现了前者到后者的格式转换。

.net生成的public key的格式:
<modulus>
jY39vkCL8xCrUK9eepK2SQ447xiU/bZmnJi6G+4ripHzOJ65YTsxJ3sEOrXCyb0P
MBXQchQ2xpE8g7PyHe4zv07/Q7hbRFJ2CJAIyFj7OD5aejOiIptMzPsYNMx5Gkbs
</modulus>
<exponent>
AQAB
</exponent>

<?php
/** 
 * Zeal Extends of ZendFramework 
 * 
 * @category   Zeal 
 * @package    Zeal 
 * @subpackage Security 
 */  
  
/** 
 * RSA公钥格式转化 
 * 
 * @category   Zeal 
 * @package    Zeal 
 * @subpackage Security 
 */  
class Zeal_Security_RSAPublicKey  
{  
    
/** 
     * ASN.1 type INTEGER class 
     */  
    
const ASN_TYPE_INTEGER 0x02;  
  
    
/** 
     * ASN.1 type BIT STRING class 
     */  
    
const ASN_TYPE_BITSTRING 0x03;  
  
    
/** 
     * ASN.1 type SEQUENCE class 
     */  
    
const ASN_TYPE_SEQUENCE 0x30;  
  
    
/** 
     * The Identifier for RSA Keys 
     */  
    
const RSA_KEY_IDENTIFIER '300D06092A864886F70D0101010500';  
  
    
/** 
     * Constructor  (disabled) 
     * 
     * @return void 
     */  
    
private function __construct()  
    {  
    }  
  
    
/** 
     * Transform an RSA Key in x.509 string format into a PEM encoding and 
     * return an PEM encoded string for openssl to handle 
     * 
     * @param string $certificate x.509 format cert string 
     * @return string The PEM encoded version of the key 
     */  
    
static public function getPublicKeyFromX509($certificate)  
    {  
        
$publicKeyString "-----BEGIN CERTIFICATE-----n" .  
                           
wordwrap($certificate64"n"true) .  
                           
"n-----END CERTIFICATE-----";  
  
        return 
$publicKeyString;  
    }  
  
    
/** 
     * Transform an RSA Key in Modulus/Exponent format into a PEM encoding and 
     * return an PEM encoded string for openssl to handle 
     * 
     * @param string $modulus The RSA Modulus in binary format 
     * @param string $exponent The RSA exponent in binary format 
     * @return string The PEM encoded version of the key 
     */  
    
static public function getPublicKeyFromModExp($modulus$exponent)  
    {  
        
$modulusInteger  self::_encodeValue($modulus,   
                                               
self::ASN_TYPE_INTEGER);  
        
$exponentInteger self::_encodeValue($exponent,   
                                               
self::ASN_TYPE_INTEGER);  
        
$modExpSequence  self::_encodeValue($modulusInteger .   
                                              
$exponentInteger,   
                                               
self::ASN_TYPE_SEQUENCE);  
        
$modExpBitString self::_encodeValue($modExpSequence,   
                                               
self::ASN_TYPE_BITSTRING);  
  
        
$binRsaKeyIdentifier pack"H*"self::RSA_KEY_IDENTIFIER );  
  
        
$publicKeySequence self::_encodeValue($binRsaKeyIdentifier .   
                                                
$modExpBitString,   
                                                 
self::ASN_TYPE_SEQUENCE);  
  
        
$publicKeyInfoBase64 base64_encode$publicKeySequence );  
  
        
$publicKeyString "-----BEGIN PUBLIC KEY-----n";  
        
$publicKeyString .= wordwrap($publicKeyInfoBase6464"n"true);  
        
$publicKeyString .= "n-----END PUBLIC KEY-----n";  
  
        return 
$publicKeyString;  
    }  
  
    
/** 
     * Encode a limited set of data types into ASN.1 encoding format 
     * which is used in X.509 certificates 
     * 
     * @param string $data The data to encode 
     * @param const $type The encoding format constant 
     * @return string The encoded value 
     * @throws Zend_InfoCard_Xml_Security_Exception 
     */  
    
static protected function _encodeValue($data$type)  
    {  
        
// Null pad some data when we get it  
        // (integer values > 128 and bitstrings)  
        
if( (($type == self::ASN_TYPE_INTEGER) && (ord($data) > 0x7f)) ||  
            (
$type == self::ASN_TYPE_BITSTRING)) {  
                
$data "�$data";  
        }  
  
        
$len strlen($data);  
  
        
// encode the value based on length of the string  
        
switch(true) {  
            case (
$len 128):  
                return 
sprintf("%c%c%s"$type$len$data);  
            case (
$len 0x0100):  
                return 
sprintf("%c%c%c%s"$type0x81$len$data);  
            case (
$len 0x010000):  
                return 
sprintf("%c%c%c%c%s"$type0x82,   
                                              
$len 0x0100,   
                                              
$len 0x0100$data);  
            default:  
                throw   
                  new 
Zeal_Security_RSAPublicKey_Exception("Could not encode value",1);  
        }  
  
        throw   
          new 
Zeal_Security_RSAPublicKey_Exception("Invalid code path",2);  
    }  
}  
  
class 
Zeal_Security_RSAPublicKey_Exception extends Exception  
{  
  
}

// example
 
$hCert openssl_pkey_get_public(  
            
Zeal_Security_RSAPublicKey::getPublicKeyFromModExp(  
                
file_get_contents("/home/zeal/certs/public.key"),  
                
"AQAB"  
            
)  
        );  
$dataToCheck "This is Data should be verified!";  
$signBinary ".................................";  
$ok openssl_verify(  
        
$dataToCheck,   
        
$signBinary,   
        
$hCert,  
        
OPENSSL_ALGO_SHA1  
);  
if (
$ok == 1) {  
    echo 
"good";  
}   
elseif (
$ok == 0) {  
    echo 
"bad";  
}   
else {  
    echo 
"error occured";  
}  
?>

如何解压rpm文件

实例:rpm2cpio a.rpm | cpio -ivmd

详细用法
解压cpio文件
cpio -idmv < filename.cpio
同样可以解压img文件:
cpio -idmv < filename.img
cpio 备份命令
备份:cpio -covB > [file|device] 将数据备份到文件或设备上
还原:cpio -icduv < [file|device} 将数据还原到系统中
常用参数:
-o   :将数据copy到文件或设备上
-i    :将数据从文件或设备上还原到系统中
-t    :查看cpio建立的文件或设备内容
-c   :一种比较新的portable format方式存储
-v   :在屏幕上显示备份过程中的文件名
-B   :让预设的blocks可以增加到5120bytes,默认是512bytes,这样可以使备份速度加快
-d   :自动建立目录,这样还原时才不会出现找不到路径的问题
-u   :更新,用较新的文件覆盖旧的文件
cpio常与find 配合使用

打包命令cpio和tar的使用

在DOS或Windows下,有各种压缩与解压缩工具软件,其主要功能是将一目录下的众多文件或子目录打包并压缩成一个文件,便于备份、组织与管理。而在Unix系统中,却无此类能打包并同时压缩的工具。 

本人在Unix系统业务使用(特别是数据管理与备份)中,经过一番研究、整理后,充分利用Unix系统本身的命令tar、cpio和compress等来做到打包和压缩,使之充当类似DOS下的压缩软件,同时在Unix系统中亦具有通用性。 

在Unix系统中,是先通过cpio或tar将众多的文件打包成一个文件库后,再用compress将文件库压缩来达到目的的。下面分别以cpio和tar来说明使用的方法和步骤。 

一、cpio 

1.文件或目录打包。 

打包有如下多种情况: 

A)含子目录打包: 

find /usr/lib -print cpio -o〉/u0/temp1.cpio 

将/usr /lib目录下的文件与子目录打包成一个文件库为/u0/temp1.cpio。 

若通过-o选项来打包整个目录下的所有文件与子目录,常先利用find目录名-print来找出所有文件与子目录的名称,通过管道“ ”传给cpio打包。 

B)不含子目录的打包:
ls /usr/lib cpio -o〉/u0/temp1.cpio

将/usr/lib目录下的文件(不含子目录下的文件)打包成一个文件库为/u0/temp1.cpio。 

C)特定文件打包:
可利用文本搜索命令grep与管道配合,可以排除或选择特定类型的文件传给cpio打包。
如:ls /usr/lib/*.c cpio -o〉/u0/temp1.cpio
或ls /usr/lib grep ′\.c$′ cpio -o〉/u0/temp1.cpio 

意思均为找出/usr/lib目录下以.c结尾的文件予以打包。 

又如:ls /usr/lib grep abcd cpio -o〉/u0/temp1.cpio ,其意为找出/usr/lib目录
下文件名中含有abcd字符的文件予以打包。 

ls /usr/lib grep -v abcd cpio -o〉/u0/temp1.cpio,其意为找出/usr/lib目录下文
件名中不含 abcd 字符的文件予以打包。-v选项在grep命令中的意思是排除含有字符串的行
列。 

如此,可充分利用Unix的管道和一些命令的强大功能来实现文件的打包。 

2.压缩: 

文件打包完成后,即可用Unix中的compress命令(/usr/bin下)压缩打包文件。对一般的文
本文件,压缩率较高,可达81%。 

compress /u0/temp1.cpio则将文件库/u0/temp1.cpio压缩为/u0/temp1.cpio.Z(自动添
加.Z并删除/u0/temp1.cpio )。 

3.解压: 

uncompress /u0/temp1.cpio.Z则自动还原为/u0/temp1.cpio。 

4.解包展开: 

将按原目录结构解包展开到当前所在目录下。若以相对路径打包的,当解包展开时,也是以相
对路径存放展开的文件数据;若以绝对路径打包的,当解包展开时,也是以绝对路径存放展开的文
件数据。因此注意若为相对路径,应先进入相应的目录下再展开。 

cd /u1 
cpio -id〈/u0/tmp1.cpio则将/u0/temp1.cpio解压到/u1下(这里假设temp1.cpio以相对路径压缩)。 

若加u选项,如cpio -iud〈/u0/temp1.cpio则文件若存在将被覆盖,即强制覆盖。 

cpio -id〈/u0/temp1.cpio *.c 则展开其中的*.c文件,类似于DOS系统中的Pkzip软件中Pkunzip -d temp1.zip解包功能。 

5.显示: 

cpio -it〈/u0/temp1.cpio [*.c] 显示文件库内的文件名称,类似于DOS系统中的Pkzip软件中Pkunzip -vbnm temp1.zip功能。 

二、tar 

1.文件或目录打包: 

tar -cvf /u0/temp2.tar /usr/lib 

将/usr/lib目录下的文件与子目录打包成一个文件库为/u0/temp2.tar。 

tar -cvf /u0/temp2.tar /usr/lib *.c *.f 

将/usr/lib目录下的*.c *.f等文件(不含子目录)打包。 

注意:如果指定文件如*.c *.f或*.*,则打包时均不含子目录。如果指定为.或*,则含
子目录。 

2.压缩: 

同上:compress /u0/temp2.tar压缩为/u0/temp2.tar.Z 

3.解压: 

uncompress /u0/temp2.tar.Z则还原为/u0/temp2.tar。 

4.解包展开: 

tar -xvf /u0/temp2.tar 

若以相对路径打包的,解包时,以相对路径存放展开的文件数据;若以绝对路径打包的,解包
时,以绝对路径存放展开的文件数据。 

若指定展开的文件名,须注意文件的目录路径。 

5.显示: 

tar -tvf /u0/temp2.tar 显示文件库内的文件名称。当指定文件名时,亦须注意文件的路
径。 

相对来说这两个命令各有优缺点。 

1)tar速度比cpio慢,且不能跨越两份存储媒体,但文件格式几乎在所有的Unix系统中都能通用,且使用简便。 

2)cpio则由于可通过管道功能,使得其打包时的文件选择、排除功能非常强,且能跨越多份媒体,并能备份特殊的系统文件。 

另外,压缩命令compress比DOS下的Pkzip的压缩率要低些。经测试,在一个目录下527个文本文件共15.7MB,在Unix打包后用compress压缩,大小为 2.1MB;相同的文件拷到DOS系统用Pkzip压缩,则大小为1.4MB。

Linux操作系统中内存buffer和cache的区别

Linux 的内存管理,实际上跟windows的内存管理有很相像的地方,都是用虚拟内存这个的概念,说到这里不得不骂MS,为什么在很多时候还有很大的物理内存的 时候,却还是用到了pagefile. 所以才经常要跟一帮人吵着说Pagefile的大小,以及如何分配这个问题,在Linux大家就不用再吵什么swap大小的问题,我个人认为,swap设 个512M已经足够了,如果你问说512M的SWAP不够用怎么办?只能说大哥你还是加内存吧,要不就检查你的应用,是不是真的出现了memory leak.
夜也深了,就不再说废话了。

在Linux下查看内存我们一般用command free
[root@nonamelinux ~]# free
             total        used       free     shared    buffers     cached
Mem:        386024      377116       8908          0      21280     155468
-/+ buffers/cache:      200368     185656
Swap:       393552           0     393552

下面是对这些数值的解释:
第二行(mem):
total: 总计物理内存的大小。
used:  已使用多大。
free:  可用有多少。
Shared:多个进程共享的内存总额。
Buffers/cached:磁盘缓存的大小。

第三行:
-buffers/cache 的内存数:200368(等于第2行的 used – buffers – cached)
+buffers/cache 的内存数: 185656(等于第2行的 free + buffers + cached)
 

由上看出,-buffers/cache反映的是被系统被实际使用掉的内存,而+buffers/cache反映的是可以挪用的内存总数。所以一般来讲我们是比较关心第三行的


第四行就不多解释了。
区别:
第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别。
这 两个的区别在于使用的角度来看,第二行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,所以他的可用内存是8908KB,已用内存是377116KB,其中包括,内核(OS)使 用+Application(X,oracle,etc)使用的+buffers+cached.
第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。
所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached.
如上例:
185656=8908+21280+155468
接下来解释什么时候内存会被交换,以及按什么方交换。
当可用内存少于额定值的时候,就会开会进行交换.
如何看额定值(RHEL4.0):
#cat /proc/meminfo
交换将通过三个途径来减少系统中使用的物理页面的个数: 
1.减少缓冲与页面cache的大小,
2.将系统V类型的内存页面交换出去, 
3.换出或者丢弃页面。(Application 占用的内存页,也就是物理内存不足)。
事实上,少量地使用swap是不是影响到系统性能的。

 

 对于共享内存(Shared memory),主要用于在UNIX 环境下不同进程之间共享数据,是进程间通信的一种方法,一般的应用程序不会申请使用共享内存,笔者也没有去验证共享内存对上面等式的影响。如果你有兴趣, 请参考:What is Shared Memory?

  cache 和 buffer的区别:
Cache:高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从Cache中直 接调用,这样就减少了CPU的等待时间,提高了系统的效率。Cache又分为一级Cache(L1 Cache)和二级Cache(L2 Cache),L1 Cache集成在CPU内部,L2 Cache早期一般是焊在主板上,现在也都集成在CPU内部,常见的容量有256KB或512KB L2 Cache。

  Buffer:缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。通过缓冲区,可以使进程之间的相互等待变少,从而使从速度慢的设备读入数据时,速度快的设备的操作进程不发生间断。

  Free中的buffer和cache:(它们都是占用内存):

  buffer : 作为buffer cache的内存,是块设备的读写缓冲区

  cache: 作为page cache的内存, 文件系统的cache

  如果 cache 的值很大,说明cache住的文件数很多。如果频繁访问到的文件都能被cache住,那么磁盘的读IO bi会非常小。

PHP debug

<?php

c();
function 
c() {
    
d("error is here");
}

function d($msg) {
    
$e = new Exception();
    
//print_r($e->getTrace());
    
$arr $e->getTrace();
    echo 
time().":".$arr[0]["file"].":".$arr[0]["line"].":".$arr[1]["function"]."n";
    echo 
$msg;
    echo 
"n";
}

?>

关于openfire+spark+smack

openfire+spark+smack 是Java领域的即时通信的解决方案, 我只是对即时通信稍有兴趣,所以才看了一下这方面的东西。
今天安装了Openfire 3.6.4, 不知道这个东西该怎么使用,只是从整体上有一个印象,对其中的一些概念混个脸熟。
Openfire 很快就安装好了,没有什么大的问题,只是安装好后,需要登录时却怎么也登录不了,刚设置的用户名和密码怎么能错呢?最后重启了一下服务,就登进去了。
现在服务是搭好了,怎么用呢? 用spark。

spark是Openfire的客户端,下载了一个web版的spark,webspark完全用flash实现的,进去之后,可以添加好友、聊天。只是在Firefox下面中文有问题,在ie下面就没有问题,应该已经有答案了,但是我暂时还不想去寻找答案。然后就是退出,没有退出按钮,但是刷新页面就退出了。

Smack是即时通信客户端编程库

为什么说基于ActiveX的“安全控件”一定是不安全的

前几天听 bugs 说,国内某C2C网站打算这个月开始禁止Firefox用户登录其网站,而说到原因,又是“出于用户安全考虑”,“Firefox无法支持其‘安全控件’”云云。

我没用过这家公司的服务,因此我也不想就这家公司发表什么评论。我觉得很有意思的一件事是,似乎大家都很信任所谓“安全控件”。

那么,什么是“安全”控件呢?简单地说,这类控件是由特定商家发布的,基于ActiveX技术实现的一种Internet Explorer插件。尽管不同的公司会以不同的方式进行实现,但这类插件通常会实现的功能,不外乎以下几种:

– 替代输入框,防止其他程序通过hook的方式得到输入框中的内容。
– 以更直接的方式从键盘读取数据,防止非本机键盘输入数据和其他程序监听键盘输入。
– 确保内存中没有某些应用程序正在运行。

很遗憾,“安全控件”往往并不能理想地达到上述目的。更有甚者,事实上这些控件几乎一定会破坏系统的安全性。

为什么这么说呢?我们人类有历史以来,从正确的假设或前提出发,都有可能会得出错误的结论;那么,从错误的假设出发,能够到达正确结论的可能性有多大呢?可想而知。

那么,回到我们刚才的话题,为什么说基于ActiveX的“安全”控件几乎一定会破坏你的系统安全呢?错误的假设又是什么呢?

首 先,在我们讨论安全系统的时候,人们往往会忽略这类系统中最重要的那个环节——用户。用户之所以是安全系统中最重要,同时也是最薄弱的环节的原因是,尽管 我们能够精确地预计机器的行为,却无法精确的估计人类的行为;我们见到抢劫银行的罪犯用枪指着工作人员或人质,却很少有人用枪指着银行使用的计算机系统 ——因为人,在一个安全系统中,也只有人是机器的最终主宰。

给用户一个保险柜,却完全不给他或她机会去了解这个保险柜的工作原理,谁又能 保证,这个用户不会把保险柜放在楼顶,任由风吹日晒雨淋,令其失去作用?这是所谓‘安全’控件的头号问题,即,它既没有真正加强用户的安全意识,也不给用 户了解它的工作原理的机会。对于用户来说,这个保险柜是个黑箱,它安全不安全,只有老天知道(为什么说它的作者也不知道呢?且看下文分解)。

“安全”控件危害安全的另一个原因是,它在鼓励不安全的用户习惯。

熟 悉Windows操作系统的朋友都知道,在Windows Vista之前,安装Active X控件是需要管理员权限的。也就是说,想要安装所谓的“安全”控件,其前提便是用户至少要以管理员身份打开1次用于安装该控件的软件,或者下载一个安装程 序,并以管理员的身份运行它。

有多少非专业用户会以非管理员身份上网呢?这个数字接近0,说接近0的原因是,有一些被他们认为很“变态” 的IT人员“挟持”的用户真的不是用管理员身份浏览网页的,为什么不能安装这个Active X控件?他们恨恨的想。随后,他们以各种方式得到了管理员权限,并安装了“安全”控件。

到现在为止,用户的安全还没有受到非常明显的伤害。但是,用户很快会发现,以管理员身份使用计算机很“方便”——没有了磁盘配额的限制,没有了各种各样让人讨厌的限制——凭什么不让我安装Active X?这个系统管理员真讨厌!

又过了一段时间,用户发现计算机越来越“好用”了。各种各样的工具条在系统中如雨后春笋一般出现,之后,打开浏览器时的首页也变得越来越“好看”,一些网页上还十分“贴心”地将关键词增加了连接指向不同的地方。“真不错”,用户想,“这才是我想要的电脑的样子”。

这并不可笑。

ActiveX无非是在诱惑用户使用管理员权限。它在破坏安全,而不是改进安全——因为写ActiveX“安全”控件的人,并不真的理解安全。

那么,话说回来,当用户改变了其良好的安全习惯之后,他得到的是什么呢?

表 面上看,“安全”控件能够防止使用hook的程序获得用户输入的敏感数据,但是事实上这个没有任何作用。在用户的安全习惯改掉之后,最简单的办法,就是让 他访问不到真正的网站,并诱使其输入那些敏感数据。举个更通俗一些的例子,把家里大门上了三道防盗门,但是没关窗户,窃贼仍然可以进来。

很 遗憾,这很浅显的道理,应用到计算机上,往往就被人们遗忘。做安全的人,就像是人民警察,需要关注每一个细节;而想要破坏安全的人,就如同小偷,可能从任 何一个没有被看到的地方进来。安全是一件困难的工作,因为防守的一方,不应该采用任何可能导致问题的办法去防御;而攻击的一方,则可以采用任何手段。

安全靠的是智慧、汗水,向公众普及安全知识,以及与用户的合作,而不是ActiveX。我不相信缺少智慧的做法会改善安全,也不相信从错误的假设能够到达正确的彼岸。