今天最郁闷的事(RC4)

 算法, 编码, 网络安全  今天最郁闷的事(RC4)已关闭评论
4月 242014
 

缘起

由于需要,引入了rc4加密算法,网上搜到了一些PHP实现,Java实现,当然,对于PHP来讲,还有openssl的实现。

网址: http://zhiwei.li/text/2011/08/7777777777777777777/

上还证明了PHP的实现和openssl的实现是相同的,由于该网址有测试例子,自己执行一边,果然如该网址所言。

由于存在java实现的需要 ,于是就测试一下,java实现和PHP实现是否相同,由于PHP的实现和openssl的实现相同,于是只比较了openssl 和java的解密结果,果然不让人省心,结果是:不同!

开始折腾

好在rc4的算法比较简单,怀疑可能是网上找到的java版本实现有问题,参考PHP的实现,自己实现了一遍java版本,结果让人纠结,自己实现的和网上找到的结果完全一样,问题在哪里?

当我再次比较openssl和php的加密结果时:发现加密结果100%不同。事情进展到这个地步,更显扑朔迷离,怀疑自己原来测试的有问题,再次测试N边,依然没有问题,其不叫人发疯。

最后,再拿出 http://zhiwei.li/text/2011/08/7777777777777777777/ 来研究;发现里面的key是md5一个密钥字符串后再pack得到的,这个也有关系?试试吧,果然有关系。至此,想起来自己两次测试使用的key是不同的,成功的那次测试,key刚好也是16字节的,而失败的那次测试的key是“testkey”,才想起来,openssl在做加密时,如果key不够长(16字节),则会在后面补 “\0″(是零,不是圈儿),但是自己实现的RC4算法,是没有在key后面补 “\0” 的。

真相大白。

郁闷啊

附测试脚本:

 

 

 

 Posted by at 下午 6:54
8月 092009
 

对于url编码一般出现在服务器端和客户端两个地方,我们的服务器端使用PHP脚本语言;而客户端一般是浏览器,这里就谈js的url编码;
关于PHP的urlencode与rawurlencode的比较:
<?php
for ($i = 0x20; $i < 0x7f; $i++) {
$str .= dechex($i);
}

$asscii = pack("H*",$str);
echo
"所有的可打印的asscii字符:(从空格到~)n". $asscii."\n";
echo
"urlencode 的结果:\n".urlencode($asscii);
echo
"\n";
echo
"urlencode 不做编码的字符:\n".preg_replace("/%.{2}/","",urlencode($asscii));
echo
"\n";
echo
"rawurlencode 的结果:\n".rawurlencode($asscii);
echo
"\n";
echo
"rawurlencode 不做编码的字符:\n".preg_replace("/%.{2}/","",rawurlencode($asscii));
echo  
"\n";

exit;
?>

输出结果:
———————————————————————————
所有的可打印的asscii字符:(从空格到~)
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~
urlencode 的结果:
+%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
urlencode 不做编码的字符:
+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz
rawurlencode 的结果:
%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
rawurlencode 不做编码的字符:
-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz

---------------------------------------------------------------------------------
比较二者的结果:
1.  数字、大小写字母都不编码
2.  减号、点号、下划线  三个不编码
3. rawurlencode比urlencode多编码一个”加号“

关于JavaScript中escape与encodeURIComponent的区别:
>>>  console.log(encodeURIComponent("统一注册1"));

%E7%BB%9F%E4%B8%80%E6%B3%A8%E5%86%8C1
>>> console.log(escape("统一注册1"));
%u7EDF%u4E00%u6CE8%u518C1

<?php
echo iconv("utf-8","gbk",urldecode("%E7%BB%9F%E4%B8%80%E6%B3%A8%E5%86%8C1"));
echo
"\n";
echo
urldecode("%u7EDF%u4E00%u6CE8%u518C1");
// 使用下面的unescape可以
//echo
iconv("utf-8","gbk",unescape("%u7EDF%u4E00%u6CE8%u518C1");
exit;
?>


输出结果:
====================
==================
统一注册1
%u7EDF%u4E00%u6CE8%u518C1
======================================

结果说明:
1. encodeURIComponent 总是把输入转换成utf8编码处理的,按字节编码
2. escape是按照unicode编码处理的,因为它也对url中不安全的字符做了编码,所以也可以在url中做编码使用,但是,服务器端不会自动解码,下面提供一个PHP版的解码函数,是用手册里找的:

<?php
function unescape($str) {
    
$str rawurldecode($str);
    
preg_match_all("/(?:%u.{4})|&#x.{4};|&#d+;|.+/U",$str,$r);
    
$ar $r[0];
    foreach(
$ar as $k=>$v) {
        if(
substr($v,0,2) == "%u")
            
$ar[$k] = iconv("UCS-2","UTF-8",pack("H4",substr($v,-4)));
        elseif(
substr($v,0,3) == "&#x")
            
$ar[$k] = iconv("UCS-2","UTF-8",pack("H4",substr($v,3,-1)));
        elseif(
substr($v,0,2) == "&#") {
            
$ar[$k] = iconv("UCS-2","UTF-8",pack("n",substr($v,2,-1)));
        }
    }
    return 
join("",$ar);
}

?>

>>> console.log(escape(" !\"#$%&'()*+,-./0123456789:;=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~"));
%20%21%22%23%24%25%26%27%28%29*+%2C-./0123456789%3A%3B%3C%3D%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
>>> console.log(encodeURIComponent("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~"));
%20!%22%23%24%25%26'()*%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~

>>> console.log(escape("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~").replace(/%.{2}/g,""));

*+-./0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz
>>> console.log(encodeURIComponent("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~").replace(/%.{2}/g,""));
!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~

结果比较:
escape未编码的字符: *+-./@_   共7个
encodeURIComponent未编码的字符: !'()*-._~  共9个

 Posted by at 上午 4:22

js提交的数据的编码

 编码  js提交的数据的编码已关闭评论
7月 152009
 

js 提交的数据的编码都是utf-8的吗?

这个问题问的不太对,我们使用js的encodeURIComponent()函数或者escape()函数编码对数据进行编码,都是按照utf-8 来编码的,所以js提交后的数据才是utf-8的,和js没有必然联系。

关于url的编码?

如果url里面含有中文字符,则浏览器会按照设置对这些字符做编码。默认utf-8编码,可以设置为ansi编码。

IE中: 选项=》高级=》总是以utf-8编码发送url

Firefox: 地址栏输入“about:config”,选项“network.standard-url.encode-utf8”,即可改变发送URL的编码方式。

相关文章:http://www.cnlei.com/blog/article.asp?id=453

 Posted by at 上午 2:49

base64 测试

 编码  base64 测试已关闭评论
7月 092009
 

XUe1eiYB1QK3WjY17wor5Q5hWqUKnSO8qrqq5NBgwvTEBZH3LhIrjt0jx6xPiNILdLkIQaXeFXl6rF99k9R22Q==

 Posted by at 上午 12:55

utf-8 & bom

 编码  utf-8 & bom已关闭评论
5月 052009
 

问题描述:在使用EditPlus等文本编辑工具,在windows下修改编码格式为UTF-8的文档时,会在文件的开头阐产生<feff>的字符。

问题影响:用IE浏览页面时,顶部会出现一行空白,查看页面的DOM结构,会发现其中的<link><script>标签会被解析到<body>标签下,在IE下,<meta>标签页会被解析到<body>标签下。

问题原因:在Windows标准下的UTF-8编码文档,是以<feff>开头来标识的,成为BOM(Byte Order Mark,字节序标记)

文档摘录:

Q: What is a BOM?

A: A byte order mark (BOM) consists of the character code U+FEFF at the beginning of a data stream, where it can be used as a signature defining the byte order and encoding form, primarily of unmarked plaintext files. Under some higher level protocols, use of a BOM may be mandatory (or prohibited) in the Unicode data stream defined in that protocol.

解决方案:

        

  • 配置EditPlus,删除BOM:“工具->首选项->文件->UTF-8标识->总是删除签名”,对应的英文版EditPlus路径为“Tools->Preferences->Files->UTF-8 signature->Always remove signature”
  •     

  • 改用其他编辑工具,推荐VIM
  •     

  • 转换为ASCII格式

相关文章: http://unicode.org/faq/utf_bom.html

 

 Posted by at 上午 12:00