前些時(shí)候,大概7月份看了些SSL協(xié)議的東西,對(duì)前人非常的佩服。把非對(duì)稱加密的安全性和對(duì)稱加密的快速性結(jié)合起來使用,保留了各自的長處。整個(gè)數(shù)據(jù)傳輸過程中,通過非對(duì)稱加密在不安全的區(qū)域安全的傳輸了用于對(duì)稱加密的密鑰,實(shí)在是創(chuàng)造性的思維。
前天晚上洗澡的時(shí)候,突然有了幾個(gè)新的想法,加上以前的一點(diǎn)發(fā)現(xiàn),就有了這篇文章和幾行代碼。現(xiàn)在覺得非對(duì)稱加密還真的很有意思啊,洗澡也很有意思,難怪阿基米德洗澡能夠發(fā)現(xiàn)浮力定理。我們不夠強(qiáng)大,可能是因?yàn)橄丛璨粔虬伞?
一. RSA替換HTTPS保證安全傳輸敏感數(shù)據(jù)
目前大多數(shù)的web應(yīng)用在注冊(cè)或者登錄的時(shí)候,或者其他任何涉及到用戶帳戶,密碼,以及信用卡號(hào)等等敏感數(shù)據(jù)傳輸?shù)臅r(shí)候,一般都毫不猶豫的采用了
HTTPS加密傳輸?shù)姆绞絹磉M(jìn)行。比如Gmail,Yahoo Mail,Live
Mail等國際性的郵箱,都是用了這種方式。確實(shí),使用HTTPS是一種比較安全的方法,但是這樣做從成本角度來說,并不是最優(yōu)的。
使用1024位密鑰的HTTPS傳輸,在相同硬件配置的情況下,性能基本上要損失掉30%左右。大量的CPU時(shí)間花費(fèi)到了對(duì)數(shù)據(jù)的加密解密以及證
書認(rèn)證,傳輸,SSL握手等方面。對(duì)于千萬用戶級(jí)別的應(yīng)用這些損失是難以忽略掉的,因此大公司一般都會(huì)購買SSL硬件加密卡,使用硬件進(jìn)行加密解密。
鑒于RSA等非對(duì)稱加密算法的public
key是可以公開的,因此可以使用這種方式來傳輸數(shù)據(jù),在某些場合取代昂貴的HTTPS傳輸。比如在郵箱的登錄入口,用戶點(diǎn)擊提交按鈕的時(shí)候,在本地使用
JS代碼將用戶名和密碼進(jìn)行RSA加密。雖然public key明文存在于JS代碼中,客戶端可見,但是僅僅具備public
key是無法推算出private key的,因此無法對(duì)加密后的數(shù)據(jù)進(jìn)行捕獲分析,加密后的數(shù)據(jù)可以安全的通過互聯(lián)網(wǎng)傳輸。
前些時(shí)間對(duì)國內(nèi)國外的一些大型網(wǎng)站登錄入口做了些分析,發(fā)現(xiàn)只有tencent的郵箱是使用的這種方式。他們用JS做了一個(gè)類,提供RSA加密算法的各種方法,在郵箱登錄表單提交的時(shí)候調(diào)用加密。JS類的地址為
http://mail.qq.com/zh_CN/htmledition2/js/safeauth.js,
有興趣的可以自己去研究。使用這種方式之后,服務(wù)端的計(jì)算量大大減少,只需要在用戶提交的時(shí)候進(jìn)行一次解密操作就可以了。而且這個(gè)解密,可以使用C語言做
成模塊,給前端展現(xiàn)語言調(diào)用,提高效率。如果有更高的安全性考慮,可以做一些改進(jìn),比如在客戶端提交表單之前,在發(fā)送數(shù)據(jù)里面加入完整性檢驗(yàn)等等,自由發(fā)
揮即可。
二. 獨(dú)立的水印系統(tǒng)
現(xiàn)在的論壇或者blog,都需要使用水印來防范強(qiáng)行破解密碼的攻擊方式,和防范發(fā)帖機(jī)器人的破壞。但是很多水印和應(yīng)用系統(tǒng)結(jié)合在一起,不方便擴(kuò)充和給第三方提供服務(wù)。這幾天想到可以使用RSA加密來實(shí)現(xiàn)一套獨(dú)立的水印算法,并且可以方便的提供給任意的第三方安全使用。
主要思路是這樣的,首先生成一對(duì)公鑰和私鑰。將公鑰發(fā)布給需要使用水印服務(wù)的第三方,私鑰保存在水印生成方。在使用方隨機(jī)生成一個(gè)字符串,隨后使
用水印方提供的public key,使用RSA算法進(jìn)行加密,將加密后的字符串發(fā)送給生成水印方。生成方使用private
key對(duì)這個(gè)字符串進(jìn)行解密,畫出圖形,將數(shù)據(jù)傳輸給水印使用方。雖然加密后的字符串在水印使用方的HTML源代碼中明文可見,但是同上所說的,沒有
private
key是無法解密的。對(duì)于安全性的一些加強(qiáng),可以考慮同時(shí)在使用方與生成方之間共享一個(gè)用于對(duì)稱加密的字符串。先對(duì)隨機(jī)生成的水印數(shù)字進(jìn)行對(duì)稱加密,然后
再RSA非對(duì)稱加密,這樣可以在萬一丟失private key的情況下,仍然不容易馬上被攻破。
為了驗(yàn)證我的這個(gè)思路,今天寫了一小段驗(yàn)證代碼,發(fā)現(xiàn)還是比較好用的。我主要是把Pear里面的RSA類扒出來了,稍微改了一點(diǎn)點(diǎn),然后做了一套測(cè)試系統(tǒng)。簡單的代碼如下,詳細(xì)的見附件。
代碼:
/*
Global.php 通用函數(shù),調(diào)用RSA類提供加密解密功能。
云舒 , 2007年10月1日
*/
function encrypt( $plain_text )
{
$public_key =
'YTozOntpOjA7czozMjoiS1vW5NNLH39farB+HPE/U0A1fs1I7ja81GJxGrrjsYEiO2k6MTtzOjM6IgEAASI7aToyO3M6NjoicHVibGljIjt9';
$key = Crypt_RSA_Key::fromString($public_key);
check_error($key);
$rsa_obj = new Crypt_RSA;
check_error($rsa_obj);
$enc_text = $rsa_obj->encrypt($plain_text, $key);
check_error($rsa_obj);
return $enc_text;
}
function decrypt( $enc_text )
{
$private_key =
"YTozOntpOjA7czozMjoiS1vW5NNLH39farB+HPE/U0A1fs1I7ja81GJxGrrjsYEiO2k6MTtzOjMyOiIButTavL72eeXVEa8E5WkAJthoHqmHIyo3HblsSJG0aiI7aToyO3M6NzoicHJpdmF0ZSI7fQ==";
$key = Crypt_RSA_Key::fromString($private_key);
check_error($key);
$rsa_obj = new Crypt_RSA;
check_error($rsa_obj);
$rsa_obj->setParams(array('dec_key' => $key));
check_error($rsa_obj);
$number = $rsa_obj->decrypt($enc_text);
return $number;
}
|
代碼:
/*
水印需求方,隨機(jī)生成字符串,然后加密發(fā)送給水印生成方
云舒 , 2007年10月1日
*/
require_once 'Global.php';
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
$str_a = $chars;
$str_b = $chars;
$str_c = $chars;
$str_d = $chars;
$str = $str_a.$str_b.$str_c.$str_d;
$enc_data = encrypt( $str );
echo
'<html><head><title>test</title></head><body><img
src="CreateImg.php?number=' .rawurlencode( $enc_data ). '"
/></body></html>';
|
代碼:
/*
水印提供方,獲取需求方傳遞過來的參數(shù),解密,畫出圖形
云舒 , 2007年10月1日
*/
require_once 'Global.php';
header('Content-type: image/gif');
if( isset( $_GET["number"] ) )
{
$enc_number = rawurldecode( $_GET["number"] );
}
else
{
exit;
}
$de_number = decrypt( $enc_number );
$chars = preg_split( '//', $de_number );
$im = imagecreate(75,30);
$bg = imagecolorallocate($im, 255, 255, 255);//背景
$font_color = imagecolorallocate($im, 0, 0, 0);//字
imagestring($im, mt_rand(5,9), mt_rand(0,5), mt_rand(0,5), $chars[1], $font_color);
imagestring($im, mt_rand(5,9), mt_rand(15,25), mt_rand(0,5), $chars[2], $font_color);
imagestring($im, mt_rand(5,9), mt_rand(30,40), mt_rand(0,5), $chars[3], $font_color);
imagestring($im, mt_rand(5,9), mt_rand(45,50), mt_rand(0,5), $chars[4], $font_color);
// 隨機(jī)點(diǎn)
for ($i=1; $i<=10; $i++)
{
imagestring($im,mt_rand(0,5),mt_rand(-5,63),mt_rand(-5,23),".",imageColorAllocate($im,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255)));
}
imagegif($im);
imagedestroy ($im);
|
三. 防御偽造域的垃圾郵件
垃圾郵件現(xiàn)在也是網(wǎng)絡(luò)上很頭疼的一個(gè)問題,使用非對(duì)稱算法的簽名功能,可以對(duì)偽造域的垃圾郵件進(jìn)行鑒別,需要郵件接收方服務(wù)器的支持。理論不多說
了,直接舉例。假設(shè)我是mail.icylife.net域,我給mail.ph4nt0m.org發(fā)郵件。但是有人自己架設(shè)了mail服務(wù)器,偽裝成
webmaster@icylife.net給
webmaster@ph4nt0m.org發(fā)郵件,試圖取得他的信任,這種問題如何處理?好辦,使用非對(duì)稱加密的簽名驗(yàn)證功能。
首先,我在
http://mail.icylife.net/publickey.txt存放我的公鑰文件,私鑰自己保存好。然后對(duì)郵件服務(wù)器進(jìn)行一些改進(jìn),對(duì)于本域發(fā)出去的所有郵件,包括郵件正文和接受者一起做一個(gè)簽名,把簽名附在郵件中一起發(fā)出去。而mail.ph4nt0m.org域中的郵件服務(wù)器在接收郵件時(shí),從
http://mail.icylife.net/publickey.txt取得我的公鑰,對(duì)簽名進(jìn)行驗(yàn)證,如果簽名不對(duì),馬上提示用戶遭受源域名偽造攻擊。對(duì)于攻擊者來說,他沒有我的私鑰,是不可能偽造出同樣的簽名的。
原文地址:http://www.icylife.net/yunshu/show.php?id=471
posted on 2007-11-25 09:29
matthew 閱讀(356)
評(píng)論(0) 編輯 收藏 所屬分類:
網(wǎng)站應(yīng)用